Search code examples
ruby-on-railsrefactoringruby-on-rails-5renderpartial

How Rails render finds variable


Simple example:

index.html.erb:

<% @posts.each do |post| %>
 <%= post.title %>
<% end %>

I can refactor this and move content to the _post.html.erb partial:

index.html.erb:

<%= render @posts %>

_post.html.erb:

 <%= post.title %>

So how Rails passes attributes of every post without creating a block? My posts_controller index action has only @posts = Post.all defined.

I thought that maybe by the name of the partial (post), but looks like its another Rails convention (plural and singular naming). Is it?

Many thanks for sharing!


Solution

  • Rails determines the name of the partial to use by looking at the model name in the collection. The full syntax to render a collection is as follows:

    <%= render partial: "post", collection: @posts %>
    

    However there is a shorthand for this:

    <%= render @posts %>
    

    According to docs:

    When a partial is called with a pluralized collection, then the individual instances of the partial have access to the member of the collection being rendered via a variable named after the partial. In this case, the partial is _post, and within the _post partial, you can refer to post to get the instance that is being rendered.

    You may find detailed explanation in rails guides