Reputation: 866
I have an index of users where I display the user name, location of user and a field called categories, which can range from zero to many items. I'm having trouble getting the categories to display properly. Here are my details:
User
has_many :user_categories
has_many :categories, :through => :user_categories
Categories
has_many :user_categories
has_many :users, :through => :user_categories
User_categories
belongs_to :user
belongs_to :category
In my user_categories table, there are three columns: id, user_id, category_id.
In my categories table, there are two columns: id and name.
In my user/index view, I have the following:
<% @users.each do |user| %>
<%= link_to user.name, user %>
<%=h user.state %>
<%=h user.categories %> ## This line is the problem
<% end %>
Where I've indicated the problem with my comment directly above, I've tried multiple variations, but somehow I'm missing it. Here are the variations that I've tried, and the results that they produce. Note that for testing, user #2 is the only one with a category that should display.
<%=h user.categories %>
displays: #<Category:0x3f40634>
Log shows:
UserCategory Load (0.4ms) SELECT * FROM "user_categories" WHERE ("user_categories".user_id = 2)
Category Load (0.4ms) SELECT "categories".* FROM "categories" INNER JOIN "user_categories" ON "categories".id = "user_categories".category_id WHERE (("user_categories".user_id = 2))
<%=h user.categories.name %> <-- Here I added .name at the end of the call
displays: category
log shows: App does not do a category load.
<%=h user.user_categories %>
displays: #<UserCategory:0x3e4d1a0>
log shows: UserCategory Load (0.4ms) SELECT * FROM "user_categories" WHERE ("user_categories"."user_id" = 2) AND ("user_categories".user_id = 2) LIMIT 1
Does not do a category load.
<%=h user.user_categories.find_by_user_id(user.id) %>
produces same results as above.
Based on this, I think that <%=h user.categories %> is the one that makes the most sense, but I've tried every variation that I can think of and they all throw exceptions.
Upvotes: 0
Views: 569
Reputation: 15292
The problem you were having is that in all three cases, you were attempting to display or operate on a collection of ActiveRecord objects. <%= h user.categories %>
and <%= h user.user_categories %>
will display the results of calling to_s
on the collection, which gives the output (#<Category:0x3f40634>
or #<UserCategory:0x3e4d1a0>
) you noted. <%= h user.categories.name %> will display the result of calling name
on the categories association.
jrhicks' answer works because he iterated over the categories and printed out the name of each one. See http://guides.rubyonrails.org/getting_started.html#hooking-comments-to-posts for a similar example - in that case, they iterate over a post's comments.
Upvotes: 1
Reputation: 14997
The model definitions look correct. You may want to check your database to ensure you've used proper conventions for your ids. I was a concerned that you tried to display all categories in the "problem line". Try looping over them:
<% @users.each do |user| %>
<%= link_to user.name, user %>
<%=h user.state %>
<%=user.categories.each do |c| %>
<%h c.name%>
<%end%>
<% end %>
Upvotes: 2