At: Getting Started with Rails — Ruby on Rails Guides
Under: 7.4 Generating a Controller
I have some questions about this controller:
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(params[:comment])
redirect_to post_path(@post)
end
end
* @comment = @post.comments.create(params[:comment])
Does this statement mean: Create a new post comment passing it the
CONTENTS of the new comment?
That's correct. Note that the attributes for the new comment (the
content, if you like) are coming from the parameters on this request
(params[:comment]) -- in other words, the information that was
submitted via a form.
* redirect_to post_path(@post)
The browser will be redirected to post_path. But, what does the object
@post represent? Is it the CURRENT post we are at?
post_path is a URL helper that gets defined when you declare
'resources :posts' in your routes.rb. It expects one parameter (in
this case, you've given it @post), and it runs the #to_param method on
this to get an ID value to insert into the generated URL. By default,
models return their ID when you call #to_param on them, so if @post
has an ID of 7, for example, then post_path(@post) will generate:
/posts/7
As for what @post is, it's not just some magic variable. If you look
earlier in your code, you actually define @post in the line:
@post = Post.find(params[:post_id])
This 'create' action is being called via a URL like this:
/posts/:post_id/comments
so you're looking up a Post object based on the :post_id that was
passed in in the URL. So, yes, in this case @post will contain the
'current' post, but only because you've written the code yourself to
make this happen. What you've got there is a common pattern for nested
resources, but do remember that @post isn't being automatically
defined for you by Rails -- you have to look up the Post object
yourself.
Chris