I read the rails guide on associations and I have also gone through a bunch of questions here on SO and on reddit, but I am just not getting associations conceptually, I think. I have two specific issues I can use as examples from an app I am working on, but I am really just trying to understand what I am doing.
Models for these examples:
List
belongs_to :user
has_many :items
Item
belongs_to :list
belongs_to :user
User
has_many :lists
has_many :items
Issue 1: Rendering associations
I know that to show the related associations in a list I can do something like this in my view:
Users/show
<%= render @list %>
Lists/_list
<ol>
<%= list.name %>
<%= render list.items %>
</ol>
Items/_item
<li><%= item.name %></li>
This seems like magic to me. I know I am calling user.list and then list.item, but when there are multiple Lists, how does rails know to separate them with the associated Items underneath? In my head when I see this code I anticipate the following as output:
<ol>
List(a)
List(b)
List(c)
<li>item(a)</li>
<li>item(b)</li>
</ol>
What I am trying to do is render each List as a Tab and render the associated Items as the tab content. Ultimately, I have multiple different List type models I want as tabs and matching multiple different Item type models to render as tab content.
Edit: I got rid of my second issue, since the post was long and it could be a separate post. Restating the above, how can a take the above collection and render it successfully in tabs where Lists are the tabs and the associated Items render as the content? I am running into issues if I use the code like this in my Users/show:
<div class="row">
<div class="col s12">
<ul class="tabs">
<%= render @lists %>
</ul>
</div>
<%=render @items %>
</div>
Lists/_list
<li class="tab col s3"><a href="#tab_<%=list.id%>"><%= list.name%></a></li>
Items/_item
<div id="#tab_<%=list.id%>" class="col s12"><%= item.name %></div>
If I try this, then my item partial gives me an error, because I can’t call list.id, and it will just render all of my items without displaying them as an associated collection with the Lists. If I nest this and put everything after the <%=render lists %> inside the list partial, then the collections work, but the closing tags end up causing issues. I am not sure how to resolve this.
Passing collections to render has very little to do with associations per say - you should consult the Layouts & Rendering guide instead.
When you call render with a collection (an array of model instances) Rails creates a loop and uses the model name and conventions to find the correct partial for each member of the collection.
Rails does not care that the collection came from an association.
Since the relationship between List and Item is bidirectional you can always access the list to which the item belongs by item.list
:
# views/items/_item.html.erb
<div id="tab_<%= item.list.id %>" class="col s12">
<%= item.name %>
</div>
Also notice that I removed the #
in the beginning of the ID since its an invalid character for an element id.