I’m having a heard time properly creating a collection according the to the Rails Guide documentation and have had to do a workaround for months.
The Problem In Detail
I have a simple model (goal) ith only one attribute (copy) ; It’s partial is straight-forward
Based on the Rails documentation, it should be as simple as the following to render a collection view (with or without decorator/helper encapsulation)
#show.html.haml of the model
- if @goals.any?
= render 'goals/goal', collection: @goals, as: :goal
= "This Project doesn't have goals, or it wasn't applicable for this particular project to have goals."
For some reason, this has not worked for me ever.
What I’ve had to do instead
Instead, I have had to do the following
= render object.goals
And then the following with the model
- if @goals.any?
= render 'shared/goal_list', object: @project
= "This project doesn't have goals, or it wasn't applicable for this particular project to have goals."
## While this works, it's a n+1 problem :/
With this in mind, what am I doing wrong to the extend I can’t take advantage of the collection syntax for partials?
When you specify collection as hash option, then you need also to specify partial name, so try this:
= render partial: 'goals/goal', collection: @goals, as: :goal
This works for me. Also without
Rails gives you a nice shorthand for this:
to_partial_path on each model to figure out which partial to render. By default,
This technique also works with a heterogeneous collection:
# @user.favorites can contain any combination of Article, Comment, and Image objects
<h1><%= @user.name %>'s Favorites</h1>
<%= render @user.favorites %>
<h1><%= article.name %></h1>
<p><%= article.content %></p>
<em>Last updated: <%= comment.updated_at %></em>
<p><%= comment.content %></p>
<h1><%= image.title %></h1>
<%= image_tag image.url %>
@joelq, @patrikbona: Thanks to the both of you on helping me improve on either approach; I was aware of the convenience of passing in @goals, but somehow made things hard than they needed to be on this occasion.
It was really handy to be informed of render method way of taking options and extra options the way it does than I realized from the documentation; ‘string’ not necessarily passing that.