I am trying to create a simple micropost application using rails...
This is my model :
Class Micropost < ActiveRecord::Base
attr_accessible :content, :name
end
Controller:
class MicropostsController < ApplicationController
def create
#blog=Micropost.new( :content => params[:content])
#blog.save
redirect_to microposts_show_path
end
def show
#mblg=Micropost
end
def index
end
end
Views:
create.html.erb
<h1>Microblogs#create</h1>
<p></p>
<%= label_tag(:content) %><br/>
<%= text_field_tag (:content) %><br/>
<%= submit_tag("submit") %><br/>
index.html.erb
<h1>Microblogs#index</h1>
<p>Find me in app/views/microblogs/index.html.erb</p>
show.html.erb
<h1>Microblogs#show</h1>
<p></p>
<%= #mblg.each.do |variable|%>
<p><%= variable.content %></p>
<%end%>
Routes.rb
Blog::Application.routes.draw do
get "microposts/create"
get "microposts/show"
get "microposts/index"
end
i am getting a template missing error... this is a fairly simple application...can you please point out where i am going wrong?
The RESTful controller in Rails has hidden actions (create, update, destroy)
The controller (if created as part of the scaffold) will have four actions visible to the user
index
new
show
edit
In our routes file, you can call
resources :microposts
which Rails will understand and create the routes for a RESTful controller.
Instead of /microposts/create you would use /microposts/new
A good example you can look at is a scaffold.
Within your Rails root directory, do the following
rails g scaffold foo bar
rake db:migrate
You will see that this creates a Foo controller and allows you to new/index/edit/show on this controller. The field that you would be entering and populating is bar.
Once you are finished playing around with this, you can do
rails d scaffold foo
rake db:rollback
Related
I'm new to rails, and I've already learnt how to do CRUD using scaffold and using resource, I wanna know how to Do CRUD without using resource, However what I want to do is create custom methods for CRUD in the controller that will be like the traditional CRUD model. Please help me with this.
Actually, for the action index / new / show / create / edit / update / destroy, this is a convention in Ruby On Rails
If I'm right and if you're trying to change their name using resources in routes.rb (Changing by exemple the new action into def my_restaurant), Rails will render
Unknown action The action 'new' could not be found for
RestaurantsController
Netherless, you can create some methods to perform some particular action into the index, and add them in the "private section" you want to hide them to the public. There is no routes attach to this method.
class RestaurantsController < ApplicationController
def index
#restautants = Restaurant.all
#restaurants.sort_by_name
end
private
def sort_by_name
#some action here
end
end
If you want to create your own name method, you can personnalise it but you can't use resources "shortcut" in the routes.rb
by exemple :
#reviews_controller.rb
class ReviewsController < AplicationController
def index
#reviews = Reviews.all
end
def update
#review = Review.find(review_params[:id])
end
def history
#some action
end
private
def review_params
params.require(:review).permit(:liked, :comment, :id)
end
end
Then add a view
#app/views/reviews/history.html.erb
Don't forget the routes :
Rails.application.routes.draw do
resources :reviews, only: [:index, :update] do
collection do
get :history
end
end
end
I hope this will help you and complete the previous answer.
as for your second question :
I still do have one doubt tho..... Will <%= form_for #post do |f| %>
this form be enough for new_post and edit_post, will it automatically
identify them? If that's not enough can you please tell me the what
comes at new_post.html.erb and edit_post.html.erb....Thanks again for
the help.
If the form is the same for your new_post and edit_post, i may suggest you to put into a partial file. (For this example I used simple_form gem)
#app/views/posts/_form.html.erb
<%= simple_form_for(#post) do |f| %>
<%= f.input :name, label: "post name" %>
<%= f.input :photo, as: :file %>
<%= f.submit "Save", class:"btn btn-small btn-success" %>
<% end %>
and then render the partial in your views new file.
#app/views/posts/new.html.erb
<div>
<h1>New Post</h1>
</div>
<%= render "form" %>
Well I hope I could help you with this answer.
Do not hesitate too to read ruby documention. You may find more information that you're looking for too.
My answer may be redundant but it's the better way for me to clearly explain it...
In oder to use your own custom methods you need to create them in your controller, setup the route and if needed create an view.
# PostsController
def create_post
# Do your create stuff here
end
def read_post
# Do your read stuff here
end
def update_post
# Do your update stuff here
end
def delete_post
# Do your delete stuff here
end
# routes
post '/create_post', to: 'posts#create_post'
get '/read_post/:id', to: 'posts#read_post'
put '/update_post/:id', to: 'posts#update_post'
delete 'delete_post/:id', to: 'posts#delete_post'
With the controller and routes setup you will only need a view for the read_post method. The best way to do that is create the file: views/posts/read_post.html.erb
There is 7 CRUD routes to Create, Read, Update and Delete.
Rails.application.routes.draw do
get "restaurants", to: "restaurants#index"
get "restaurants/new", to: "restaurants#new", as: :new_restaurant
post "restaurants", to: "restaurants#create"
# NB: The `show` route needs to be *after* `new` route.
get "restaurants/:id", to: "restaurants#show", as: :restaurant
get "restaurants/:id/edit", to: "restaurants#edit", as: :edit_restaurant
patch "restaurants/:id", to: "restaurants#update"
delete "restaurants/:id", to: "restaurants#destroy"
end
So once the route create, you can create in the controller, the action that you need
class RestaurantsController < ApplicationController
def index
#restaurants = Restaurant.all
end
end
and the view
app/views/restaurants/index.html.erb.
The best practice is to create only the routes that you will need and to work in silos.
1 route, 1 controller action, 1 view.
I'm trying to make a form that will post to a database, I'm really struggling at the moment and i'm getting this error.
NameError in AddController#index
uninitialized constant AddController::Newevents
Could you advise what i would need to do?
Heres all the code i have
Form
<%= simple_form_for(#newevent) do |f| %>
<%= f.input :eventname, required: true %>
<%= f.input :eventdate %>
<%= f.input :eventimage %>
<%= f.button :submit %>
<% end %>
controller
class AddController < ApplicationController
def index
#newevent = Newevent.new
end
end
Model
class Newevent < ActiveRecord::Base
def event_params
params.require(:Newevent).permit(:eventname, :eventdate, :eventimage)
end
end
Routes
resources :add
Edit
i now have this error undefined methodnewevents_path'` after changing this
#newevents = Newevent.new
It seems that you miscopied your code here. The error message indicates that your index method actually looks like this
def index
#newevent = Newevents.new
end
Remove the s from the end of Newevent and it should work.
RE: your edit
Your routes declare that you have a resource named add, if you want to show and create your Newevent objects, then you should create a controller for that. Declare resources :newevents in your routes and create a controller to handle it.
You should research RESTful routes, because that's what Rails's resource routing works best with. The form to create a new object should be displayed by the new action and not index.
You should be using create method instead of index if you are using POST http method. index will be called if you are using GET method and it shouldn't be used to post the form data. Refer this link for more information on rails routing.
class AddController < ApplicationController
def create
#newevent = Newevent.new
end
end
I have two controllers Businesses and Specials. They both have a tables one Business and one Special. They are relational. The controller Specials has a column called business_id which is connected to the database Business and that id. Im trying to make it so when you click on the link on the Specials controller index view the link to the business it goes to the Businesses controller show view so the link is Business/nameofbusiness
--- Businesses Controller ---
class BusinessesController < ApplicationController
def show
#business = Business.find(params[:id])
end
end
--- Business Model ---
class Business < ActiveRecord::Base
has_many :specials
end
-- Specials Controller
class SpecialsController < ApplicationController
def index
#specials = Special.all
end
def show
#special = Special.find(params[:business])
end
end
-- Special Model ---
class Special < ActiveRecord::Base
belongs_to :business
end
--- Index View of Specials Controller --
<h1> Specials </h1>
<% #specials.each do |special| %>
<hr />
<h4> <%= link_to special.name, special %> </h1>
<h6> <%= link_to special.business.business_name, business_path(#special) %> </h6>
<p> <%= special.description %> </p>
<hr />
<% end %>
You'll have to create a new route for that, since business_path will be converted to something like businesses/:id, so in your config/routes.rb you can add:
get "/businesses/:business_name" => "businesses#show", :as => :business_show
and of course on your controller you can't do a plain find anymore, so instead you can use something like this:
#business = Business.find_by_name(params[:business_name])
NOTE: here you would be having two routes with different params going to the same action (the business_path will continue to send requests with params[:id] to the show action) and there will be issues due to that, so you can do two things:
If you're not going to use the default show route anymore (eg: businesses/:id), you can add this to your routes file:
resources :businesses, except: :show
Create a separate action for handling that kind of request, so instead of using show, use show_business for example.
get "/businesses/:business_name" => "businesses#show_business", :as => :business_show
The link_to helper makes this super easy. Use it this way.
<h6> <%= link_to special.business.business_name, special.business %> </h6>
If you want the name of the business in path you need to do more. The gem FriendlyId was made for this. Here's a great (free) railscast on how to use it.
In the rails guides tutorial creating a blog app after we create the rails app and create a resources in the routes then we start working on a form_for for creating a posts title and text in the guide it tells me that we need to add this line <%= form_for :post, url: posts_path do |f| %>
the posts_path helper is passed to the :url option. What Rails will do with this is that it will point the form to the create action of the current controller, the PostsController, and will send a POST request to that route.
so what am trying to understand is the passing to 'create action' you see I have a simple app where i want is when a text is entered in the title field and the submit button is entered I want it to pass to the create action where I just out put the text in the create action view or another view, the rails guide goes through teaching the 'CRUD' but I just want to understand How to build an app that doesn't use 'CRUD' for instance an app that takes an input and outputs it in another view?
my form:
<h1>Here Lets create a simple post</h1>
<%= form_for :post, url: posts_path do|f| %>
<p>
<%= f.label :title %>
<%= f.text_field :title %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
posts controller:
class PostsController < ApplicationController
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
end
def post_params
params_require(:post).permit(:title)
end
end
create view:
<h1>THis is the post create action</h1>
<%= #post.title %>
routes:
Learnnobase::Application.routes.draw do
resources :posts
root "welcome#home"
end
Right now am getting an error stating uninitialized constant PostsController::Post highlighting my create method? I've done so many rails app tutorials using 'CRUD' I really wanna learn building a simple app without using 'CRUD', I was trying to experiment with this app even though I do use the create action of "CRUD".
We generally use Rails to build database-backed applications, but for learning purposes, you can do it this way.
The problem you are facing here is: You are tyring to create an object of the Post class, that will be the model in the example you are referring to. The error comes up since you have not created the Post model.
To meet your requirement you can make your create action be:
def create
#post = post_params #this will be a hash
end
Then change your view to:
<h1>THis is the post create action</h1>
<%= #post[:title] %>
Since you have started with rails, I would ask you how did your posts/new page load with #post = Post.new in posts/new action when you do not have post model file and class?
It is not possible. Second, with what Manoj Monga has suggested you to use params by assigning it to an instance variable(wrong way to do so with params), if you try to use create_path for posts resources which literally is '/posts' you would end up hitting posts/index action.
Rails has standard reserve action names like :index(GET, /posts), :show(GET, /posts/:id), :new(GET, /posts/new), :create(POST, /posts), :edit(GET, /posts/:id/edit), :update(PATCH, /posts/:id) You should not attempt at overriding their purpose.
What I understand that you did use post model class and loaded posts/new page, then you deleted post model class and tried with what you have asked about in your question. You should respect Rails' standards.
I've been stuck on this for a bit and can't figure out the exact reason why I'm getting the following error:
undefined method `entries_path' for <%= form_for(#entry) do |f| %>
entry_controller:
class EntryController < ApplicationController
def index
end
def new
#entry = Entry.new
end
def create
#entry = Entry.new(user_params)
if #entry.save
redirect_to #entry
else
render 'new'
end
end
private
def user_params
params.require(:entry).permit(:comment, :flag)
end
end
routes has:
resources :entry
and the new page where the error occurs:
<%= form_for(#entry) do |f| %>
<%= f.label :comment %>
<%= f.text_field :comment %>
<%= f.label :flag %>
<%= f.text_field :flag %>
<% end %>
I can't figure out why I'm getting this error.
form_for needs to reference the path associated with #entry (i.e. entries_path), but your routes.rb file uses the singular form of the resource (:entry) rather than the required plural form (:entries), so the proper path names don't exist.
Rails models use the singular form, but the Rails database, controllers, views use the plural form and this is reflected in the routes file. One way to remember this is that a model is describing a single class that each object belongs to. Everything else, pretty much, is responsible for managing multiple instances, so while they themselves are singular (e.g. Controller), they refer to the objects they manage in the plural form (e.g. EntriesController, controller/entries directory).
See Ruby on Rails plural (controller) and singular (model) convention - explanation for more discussion of this.
Controller and views should always be treated in plural form. For example, if you have an object Book, then the controller declaration should be
class BooksController < ApplicationController
and the views( new, edit, show, index ) should be inside a folder named
/books
Also, the declaration of routes should be in plural form. In this case, the routes should be declared as
resources :books
You could try to generate the controller and view folder by running in your terminal:
rails generate controller name_of_object_in_plural_form( for sample, books)
The script will generate a controller named books_controller.rb and /books folder under /views