Satya's blog - Rails has_many :through

Dec 01 2007 23:02 Rails has_many :through

There are any number of blogs out there that will tell you how to do simple :through associations in Ruby on Rails. None of them will tell you how to set up checkboxes to populate and manage this many-to-many relation.

Suppose you have a model, 'rumor', which can have zero or more categories. Yes, this is basic acts_as_taggable functionality. Well, your form can have the following code, where you iterate over the categories and for each one, set up an input checkbox.

<% @categories.each do |t| %>
<input id="rumor_category_ids_<%= t.id -%>" name="rumor[category_ids][]" type="checkbox" value="<%= t.id -%>" 
<% if @rumor.categories.include?(t) %>checked="checked"<% end %> /> 
<label for="rumor_category_ids_<%= t.id -%>"><%= t.name %></label> 

The checkbox id attribute is simply parent model name, then the category_id column name pluralized (since it's an array of checkboxes) and the category id attribute's value. Example, rumor_category_ids_1. The name attribute follows rails convention, too: the parent model (rumor), the foreign key pluralized (category_ids) to indicate that it's an array, and an empty bracket to show where the IDs would go, in a semi-metaphorical way. So we get the array of IDs of the checked categories as params[rumor][category_ids] in our controller. the value attribute is, of course, the lookup table's (category, here) id attribute.

Since this could be the display of an existing record, we check the checkbox if the existing object (@rumor)'s categories include the current category of the loop (t). And the last line, we have a nice clickable label.

Last updated: Dec 06 2007 14:00

Tag: rails howto