HABTM Checkboxes

August 3, 2007

When working with Rails, one of the 2 methods for dealing with many-to-many relationships is "Has and Belongs to Many" (HABTM). Despite it's declining popularity, I'm still under the belief that HABTM is still a viable choice if you just have a simple assocation between 2 models. Of course, that opinion is subject to change.

So until we've figured out how to full get rid of HABTM with "Has Many Through", we'll need to be creating interfaces to allow users to choose a set of models to associate to another model. One common way of doing this is using checkboxes, as is so eloquently explained in Railscast 17: HABTM Checkboxes.

One gotcha that pops up when dealing with a HABTM, as is pointed out in the Railscast, occurs when you are editing a model, and you want to remove all of the associations, in other words, remove a certain product from all categories. Because of the way HTML and HTTP works, if you uncheck all of the check boxes, no parameters get sent in the HTTP request at all. The Rails model and controller interpret the lack of parameters to mean "you don't want to change that value at all", so instead of removing all the categories for the product, the set of categories a product is in doesn't change at all.

The suggested work around for this in the Railscast is to add this following code to you controller:

params[:product][:category_ids] ||= []

This will initialize the category_ids array to an empty array if it doesn't exist. This works, but modifying the params in the controller could be considered dubious. A co-worker of mine pointed out an alternative to me today that I think is cleaner. Instead of putting the above code in your controller, you could put this code in the view:

<!-- products/_form.rhtml -->
<%= hidden_field_tag "product[category_ids][]", "" %>
<% for category in Category.find(:all) %>
<div>
    <%= check_box_tag "product[category_ids][]", 
        category.id, @product.categories.include?(category) %>
    <%= category.name %>
</div>
<% end %>

The 2nd line, the first one after the comment, is the only one added. That will send an empty string, which Rails will add to the array in the params, but then will be happily ignored by the model. The result is that the category_ids array in the params will never be nil, so no additional code is needed in the controller.

Posted in Technology | Tags Checkboxes, Rails, Ruby, HABTM

Comments Comments Feed

1. Ahoy,

I have a solution for has_many associations (therefore for habtm too) with a single select box and a list of checkboxes to store the associations.

It uses client-side javascript, no AJAX, and the code is simpler than Ryan Bates'complex forms.


Take a look at: http://clair.ro/rc/2008/10/13/has_many-with-select-box-and-checkboxes/

# Posted By cs on Monday, October 13 2008 at 10:35 AM

2. Have you found any new elegant way of doing this?

# Posted By Rex on Sunday, February 22 2009 at 9:03 PM

3. Indeed, it's a cleanr solution. Thanks for sharing.

# Posted By Andrés Mejía on Wednesday, July 7 2010 at 12:30 AM

4. linda
Gucci Designer handbags are not rightful simple leather lacoste Gucci Outlet men embroidered carrier items imperative for the jurisdiction of girlie items drink in toiletries, make-up and authorize UGG Boots. No girlfriend! An authentic designer MBT Shoes speaks volumes about you and implies that you are a witch of style, seasoning and UGG Boot. However, you power serve as assurance that having an authentic nike dunk is facade your carry through. You Cheap Gucci substitute wonderment if you passion to crack into MBT Discount savvy a blasting move shift you have your pocket dunk shoes and house till you dispatch to that unknown pace when you be credulous saved enough to buy your confess authentic designer bag.

# Posted By Gucci Outlet on Monday, August 30 2010 at 8:59 AM

5. Diamond earrings and tiffany silver bracelets can be a romantic gift for any occasion. These can be as simple as a single stone silver tiffany earrings or as elaborate as chandelier silver tiffany earrings embellished with numerous stones. It is important to keep in mind the individual you are buying the gift for. If the recipient of the gift would like something that they can wear every day, tiffany promise rings are the way to go. However if the gift recipient enjoys getting dressed up for a night on the town or goes to formal affairs on occasion, the chandelier tiffany inspired rings are the perfect gift.

# Posted By tiffany inspired earrings on Tuesday, August 31 2010 at 2:19 AM

6. Find ugg and Australian sheepskin boots, learn the history behind the Ugg boot, and when and what to wear with Cheap ugg boots, as well as cleaning and caring forAuthentic Ugg boots,Cheap ugg cardy boots,20%-40% high discount

# Posted By p on Wednesday, September 1 2010 at 2:11 PM

7. There are many people like to searching the famous brand shoes
online.
Nike Air Max
is always the best choice and you will fall in love when the first sight.As the most sought-after products,
the famous brand shoes
are not only fashionable but also practical.Nike Air Max which is one of the hottest shoes in the summer are available in a variety of styles, colors and materials.
Nike Air Max shoes
are designed for yourself.You can pick up a pair now at www.online268.com.

# Posted By online268 on Wednesday, September 1 2010 at 4:21 PM

8.
There is no doubt that when looking for Cheap nfl jerseys to buy you still want nfl shop to get something buy nfl jerseys authentic. Now that you know that there are Cheap nfl jerseys outlets out there for you to purchase and they are high quality and authentic, and I think you can buy the best one.

# Posted By fewrewree on Wednesday, September 1 2010 at 7:14 PM

9. Coach
Coach handbags
Coach bags
replica Coach

# Posted By ss on Thursday, September 2 2010 at 7:47 AM

Add a Comment

(If you leave this blank, your IP address will be displayed instead)

(Optional, will not be displayed on the site)