I am trying to render partials for a collection of @entries to a shared view.
In one controller, I am doing it directly to render all the @entries in the view.
<%= render(:partial => '/shared/entry', :collection => @entries) %>
On another controller, I am doing it through bookmarks. As a result, the collection is @bookmarks.entries
<%= render(:partial => '/shared/entry', :collection => @bookmarks.entries) %>
Here is my /shared/_entry.html.erb :
<div>
<%= link_to_unless_current entry.tag_list, tag_path(entry.tag_list) %>
</div>
I get the following error from the Bookmark controller, but the other controller works fine:
undefined method `tag_list' for #<Bookmark:0x007fad659b32b8>
It looks like it happens because even thought the collection is @bookmarks.entries, it is still recognizing it as a Bookmark and not as an Entry. If I change the view to the following, it works on the Bookmark, but then fails on the other controller:
<div>
<%= link_to_unless_current entry.entry.tag_list, tag_path(entry.entry.tag_list) %>
</div>
How can I make the Bookmark collection just to have entries?
What's happening here is that you've used the wrong syntax by mistake, and it just happens that there is a method with the name you've used, existing in Rails/Ruby already.
If you are expecting this
to return a list of Entry objects, then it won't. If @bookmarks is a collection of Bookmark objects, and a @bookmark
has_many :entries
, and you want to get all entries associated with all the bookmarks, you would do something like@bookmarks.collect(&:entries).flatten.uniq
.So, the syntax is wrong, and it should break, except that it just so happens that the Enumerable module, which is included in the Rails collection class, has a method called "entries", which returns an array of the items, which in this case are all Bookmark objects. So, the partial is expecting an Entry and it's getting a Bookmark, and that's what that error is telling you: you're calling
tag_list
on a Bookmark object.