Multiple Checkboxes with HABTM

June 29, 2007 at 9:36 am 12 comments

Has and Belongs to Many with Multiple Check boxes

So if you are trying to do a multiple select of checkboxes and using habtm in your project, but when you submit the form, only one value was available in your controller. While you try to edit records in database but because of some error you get back to the pre field form and you found that the checkboxes checked by you gone ,then here’s the solution

Model:

	class Customer < ActiveRecord::Base
		has_and_belongs_to_many :intrests
	end

Controller code:

class CustomersController < ApplicationController
   def create
      if request.post?
         @customer=Customer.new(params[:customer])
         @customer.save
      end
   end

   def edit
      @customer=Customer.find_by_id(params[:id]) if params[:id]
      if @customer
         if request.post?
            if @customer.update_attributes(customer)
               flash.now[:message]="Update successfully "
            end 
         end
      else
        flash[:message]="Page requested by you does not exists"
      end
   end
end

Your View:

 <% form_for :customer,  do |f| -%>
    First Name:
      <%= f.text_field :first_name  -%>
    Last Name:
      <%= f.text_field :last_name -%>
      <% for  intr in total_intrests -%>
         <%= check_box_tag "customer[interest_ids][]", "#{intr.id}", interest(intr) -%> # interest is a helper method
         <%= "#{intr.name}" -%>
      <% end -%>
   <% end -%>

helper method

   def interest(i)
      if @customer
         @customer.interests.include?(i)
      else
        false
      end
   end

View generate a checkbox for every interest(all_interest=Interest.find(:all)). The name of the input is significant obviously. The trailing “[]” on the name means the end result will be the list of checked ids. This list will be stored on the @params[‘customer’] hash with the key ‘interest_ids’. When the controller calls @customer.update_attributes(@params[:customer]), it tries to call @customer.key= for each of the keys on @params[:customer]. What’s important to realize is that these keys don’t have to actually be attributes on the Customer model. All that’s important is that there’s a key= method on the model. Model automatically contains a “collection_ids=” method for habtm and has-many associations.

This method will load the objects identified by the ids and call the “interest=(list)” method on the model with the freshly loaded list. This method in turn, will compare the list to the current list of interests and delete/add interests as necessary.

Entry filed under: CSV, HABTM, Rails, ror.

How to generate CSV files in Rails Varify Email address Format

12 Comments Add your own

  • 1. mahesh  |  July 12, 2007 at 7:52 pm

    thank u but some what unable to understand clearly,please give me in some datailed one

  • 2. Satish Chauhan  |  July 13, 2007 at 11:08 am

    hi mahesh

    Let me know what point you are not getting ?
    and what more detail you want ?

    Satish Chauhan

  • 3. mahesh  |  July 13, 2007 at 7:17 pm

    how to display the content of FCK Editor without displaying HTMLtags at users display in ruby on rails

  • 4. mahesh  |  July 16, 2007 at 7:14 pm

    thank u for reply,
    i am creating a list of items with every item containing checkboxes.as i have to select some items by clicking checkbox. and when i click on the delete button i have to delete the selected items from the list,and i have to display the same page with remaining list of items.
    for that i have declare an array for checkboxes and how i can pass the array to controller to delete the items..
    can u please give me the explanation for this …..

  • 5. Satish Chauhan  |  July 17, 2007 at 8:30 pm

    If it is possible, show me your code

    i will try to solve your problem

  • 6. Blumer  |  September 28, 2007 at 11:35 pm

    Just a quick note to say thanks for sharing this solution–quick, easy, and elegant! Filed away in my library of useful examples.

  • 7. links for 2007-09-29 « Bloggitation  |  September 29, 2007 at 5:49 am

    […] Multiple Checkboxes with HABTM « Ruby on Rails (tags: ruby rails programming) […]

  • 8. Jason  |  October 31, 2007 at 6:50 pm

    I am a newbie with Ruby on Rails, I really need help with been able to select multiple checkboxes on a form, then using a button to export the selected checkboxes to excel.

    Export skills by person

    0%>

    Select
    Last Name
    First Name
    Enterprise Id

    “export_person_excel”,
    :id => person %>

    No people.

    Please help…what to i need to change or add in the controller etc…detailed explanation is welcome 🙂

    thanks in advance

  • 9. Jared Howard  |  January 3, 2008 at 3:51 am

    I’ve been using this type of HABTM control recently but I’ve come across a problem with it. What happens if you unassign all the customer’s interests? If no checkboxes are checked then the variable doesn’t exist when the form submits, there will be no params[:customer][:interest_ids]. I’ve coded for this problem by doing this:


    if params[:customer][:interest_ids].nil?
    @customer.connection.delete("DELETE FROM customers_interests WHERE customer_id = #{@customer.id}")
    end

    Any other (or better) ways?

  • 10. Jared Howard  |  January 3, 2008 at 4:00 am

    And then, of course, the connection.delete part can (and probably should) be moved to the model:

    controller:
    if params[:customer][:interest_ids].nil?
    @customer.remove_all_interests
    end

    model:
    def remove_all_interests
    connection.delete(“DELETE FROM customers_interests WHERE customer_id = #{id}”)
    end

  • 11. Ari  |  February 10, 2008 at 12:04 am

    I was having exactly the same problem. This is a great solution! Thanks

  • 12. gerhard  |  February 15, 2008 at 12:38 am

    If you use ‘check_box’ instead of ‘check_box_tag’, ‘interest_ids’ exists even if all checkboxes are unchecked (check_box ads a hidden value for the ‘unchecked’ case).
    You can drop your ‘remove_all_interests’ workaround if you’re using the following code:


    :interest_ids, :checked => interest(intr)}, “#{intr.id}”, "") -%>

    or


    :interest_ids, :checked => interest(intr)}, “#{intr.id}”, "") -%>

Leave a comment

Trackback this post  |  Subscribe to the comments via RSS Feed


Calendar

June 2007
M T W T F S S
 123
45678910
11121314151617
18192021222324
252627282930  

Most Recent Posts