Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 4 - checkboxes for has_and_belongs_to_many association

I recently had a problem getting checkboxes to work for a has_and_belongs_to_many (HABTM) association in Rails 4. I was able to find the information on how to get it working correctly in a few disparate places, but thought it would be good to document the few simple steps necessary to get it working correctly in one place here on StackOverflow.

As a setup assume a model of Kennel with a HABTM association to Handler.

class Kennel
    has_and_belongs_to_many :handlers
end
like image 720
Coenwulf Avatar asked Feb 10 '14 21:02

Coenwulf


3 Answers

This is all you need to do for the form: Don't do it manually when there is a built in helper.

<%= form_for @kennel do |f| %>
  <%= f.collection_check_boxes(:handler_ids, Handler.all, :id, :to_s) %>
<% end %>
like image 50
JP Duffy Avatar answered Nov 19 '22 22:11

JP Duffy


The form should have something like this:

<%= form_for(@kennel) do |form| %>
    ...
    <div class="field">
        <div class="field_head">Handlers</div>
        <%= hidden_field_tag("kennel[handler_ids][]", nil) %>
        <% Handler.order(:name).each do |handler| %>
            <label><%= check_box_tag("kennel[handler_ids][]", id, id.in?(@kennel.handlers.collect(&:id))) %> <%= handler.name %></label>
        <% end %>
    </div>
    ...
<% end %>

The hidden_field_tag allows the user to uncheck all the boxes and successfully remove all the associations.

The controller needs to allow the parameter through strong parameters in the permitted_params method:

params.permit(kennel: [:city, :state
    {handler_ids: []},
    :description, ...
    ])

References:

  • http://railscasts.com/episodes/17-habtm-checkboxes
  • https://coderwall.com/p/_1oejq
like image 39
Coenwulf Avatar answered Nov 19 '22 23:11

Coenwulf


I implement has_and_belongs_to_many association this way:

model/role

class Role < ActiveRecord::Base
  has_and_belongs_to_many :users
end

model/user

class User < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

users/_form.html.erb

---
----
-----
 <div class="field">
        <% for role in Role.all %>
            <div>
                <%= check_box_tag "user[role_ids][]", role.id, @user.roles.include?(role) %>
                <%= role.name %>
            </div>
        <% end %>
    </div>

users_controller.rb

def user_params
    params.require(:user).permit(:name, :email, { role_ids:[] })
  end

Intermediate table_name should be roles_users and there should be two fields:

  1. role_id
  2. user_id
like image 9
A H K Avatar answered Nov 19 '22 23:11

A H K