Following ROR’s guides getting started tutorial, I am making a blog having two models – Post & Comment – with following associations in config/routes.rb file:
resources :posts do
resources :comments
end
As such, comments and comment form is shown on the blog’s view/posts/show.html.erb page for display reasons. However, I am stuck in understanding what does @post, @post.comments.build means in the following snippet of code:
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Also, during re-factoring, the author has moved code to display comments to the view/comments/_comment.html.erb partial and has rendered it in view/posts/show.html.erb using
<%= render @post.comments %>
This will now render the partial in app/views/comments/_comment.html.erb once for each comment that is in the @post.comments collection. As the render method iterates over the @post.comments collection, it assigns each comment to a local variable named the same as the partial, in this case comment which is then available in the partial for us to show.
Q: How does rails infer the partial name and the variable to be passed to the partial for displaying comments from above line of code?
Also, can you explain what does the following statement means in terms of the above mentioned blog application. Ref: http://guides.rubyonrails.org/getting_started.html
The @post object is available to any partials rendered in the view because we defined it as an instance variable.
First question.
What does
[@post, @post.comments.build]mean?Basically this is instantiating what is going to be produced in your form. The
@post, and it’s also going to build@post.comments. But this seems unnecessary, and I think you could accomplish the same with just :Unless the form it self on producing the form, also gives you the chance to write comments at the exact same time.
Second question.
The way partials work is that so long as they’re the same name as the object. In your case
_comment.html.erbis the same name as your modelComment. So Rails will auto-magically assume that is what you are looking for.If you were to change the name of your partial to something else, you’d write more specifically this :
Update
Ah ok I didn’t realize what form you were referring to. This one specifically that instantiates this :
Is referring to the Comment model. But its saying that the comment’s parent is
@post. So that the comment model you’re specifically referring to is the child of@post, and is going to be built on or appended to your array of comments that is associated with that@post.