Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - how to store "has_many" checkboxes association in database?

I have the table User and the table Categories.

The relation between these two tables:

  • user has_many :categories
  • category belongs_to :user

I would like to display on the user's (standard) edit page the list of categories with checkboxes. When this user would check some of the checkboxes, I would like to save them and then display as checked when he open the page the next time.

But how to render the checkboxes in the view? And how to store information about what checkboxes the user checked in database? My first idea was like to create a table like user_categories with user_id and category_id, but not sure how effective this approach is.

What's the best way to implement this task nowadays?

like image 864
user984621 Avatar asked Oct 28 '13 11:10

user984621


3 Answers

Not much has changed recently except for the introduction of strong parameters. You still want to use either a has_and_belongs_to_many or has_many :through relationship and then just assign the ids of the relationship directly. You'll need to setup a form that passes an array of ids that are selected so that they come in like {user: {category_ids => [1,2,3]}.

class User < ActiveRecord::Base
  has_and_belongs_to_many :categories
end

In the controller

def update
  current_user.update(user_params)
end

def user_params
  params[:user].permit(
    {:category_ids => []}
  )
end
like image 86
Peter Brown Avatar answered Nov 02 '22 16:11

Peter Brown


you can take the habtm approach.

then in user form partial, add field

 <div class="field"> 
   <%= f.label "Categories" %><br /> 
   <% for category in Category.all %> 
   <%= check_box_tag 'user[category_ids][]', category.id, 
  @user.category_ids.include?(category.id), :id => dom_id(category) %> 
   <%= label_tag dom_id(category), category.name, :class => "check_box_label" %> 
   <% end %> 
 </div>

where category.name is the field in your category model.

this should work.

then in your user index view,

<% @users.each do |user| %>
<%= user.categories.collect(&:name).join(",") %>
<% end %>

it should show the associated category of the user. dont forget to add :category_ids in your user model attr_acessible field. else mass assingment security will pop up

like image 36
curiousCoder Avatar answered Nov 02 '22 14:11

curiousCoder


You probably want to implement a many to many relationship using has_many :through rather than having categories belong to a user (means a category can only ever have one user, is that what you want?

Have a read of has_many :through to get you started. Once you've done that the checkboxes are easily implemented using the collection_check_boxes helper.

like image 34
Matt Avatar answered Nov 02 '22 15:11

Matt