2

Ok so I have the following setup and need some direction. I have wasted almost 2 days on this issue and I need to move on:

So Roles and Permissions are associated through RolePermissions Role -> RolePermission -> Permission

I am looking to create a grid of checkboxes that allow me to edit all roles and permissions at the same time.

This is what im looking for visually: Roles / Permissions checkbox grid

Any help would be greatly appreciated! Also, I am using simple_form and bootstrap.

madth3
  • 7,275
  • 12
  • 50
  • 74
Bill Garrison
  • 2,226
  • 3
  • 34
  • 75
  • There is a railscast on habtm with checkboxes you may be able to adapt it for your needs: http://railscasts.com/episodes/17-habtm-checkboxes – DickieBoy Mar 11 '13 at 18:01
  • Can you please put this comment into an answer because using that railscast I was able to create something and id like to give you credit for pointing me in the right direction :) – Bill Garrison Mar 11 '13 at 18:21

2 Answers2

2

Try this,

# /config/routes.rb

resources :roles do
  collection do
    get :edit_multiple
    put :update_multiple
  end
end


# /app/controllers/roles_controller.rb

class RolesController < ApplicationController
  def edit_multiple
    @roles = Role.all
    @permissions = Permission.all
  end

  def update_multiple
    params[:roles] = {} unless params.has_key?(:roles) # if all checkboxes unchecked.
    Role.all.each do |role|
      # this allows for 0 permission checkboxes being checked for a role.
      unless params[:roles].has_key?(role.id.to_s)
        params[:roles][role.id] = { permission_ids: [] }
      end
    end
    @roles = Role.update(params[:roles].keys, params[:roles].values)
    @roles.reject! { |r| r.errors.empty? }
    if @roles.empty?
      redirect_to edit_multiple_roles_path
    else
      render :edit_multiple
    end
  end
end


# /app/views/roles/edit_multiple.html.erb

<%= form_tag update_multiple_roles_path, method: :put do %>
  <table>
    <tr>
      <th></th>
      <% @permissions.each do |permission| %>
        <th><%= permission.name %></th>
      <% end %>
    </tr>
    <% @roles.each do |role| %>
      <tr>
        <th><%= role.name %></th>
        <% @permissions.each do |permission| %>
          <td><%= check_box_tag "roles[#{role.id}][permission_ids][]", permission.id, role.permissions.include?(permission) %></td>
        <% end %>
      </tr>
    <% end %>
  </table>

  <%= submit_tag "Save" %>
<% end %>


# /app/models/role.rb

class Role < ActiveRecord::Base
  has_many :role_permissions
  has_many :permissions, through: :role_permissions
  attr_accessible :name, :permission_ids
end

It's a combination of http://railscasts.com/episodes/17-habtm-checkboxes and http://railscasts.com/episodes/165-edit-multiple-revised

EDIT:

Just noticed I got the table heading backwards. This will put roles across the top and permissions down the side,

# /app/views/roles/edit_multiple.html.erb

<%= form_tag update_multiple_roles_path, method: :put do %>
  <table>
    <tr>
      <th></th>
      <% @roles.each do |role| %>
        <th><%= role.name %></th>
      <% end %>
    </tr>
    <% @permissions.each do |permission| %>
      <tr>
        <th><%= permission.name %></th>
        <% @roles.each do |role| %>
          <td><%= check_box_tag "roles[#{role.id}][permission_ids][]", permission.id, role.permissions.include?(permission) %></td>
        <% end %>
      </tr>
    <% end %>
  </table>

  <%= submit_tag "Save" %>
<% end %>
Sam
  • 3,047
  • 16
  • 13
  • I had come up with another solution but this is much better / elegant – Bill Garrison Mar 11 '13 at 18:54
  • Yeah i had noticed the heading when implementing and changed it myself....the solution I had was very similar to this and this helped me out immensely. THANK YOU! – Bill Garrison Mar 11 '13 at 19:03
  • One slight problem I have run into. When all check-boxes are unchecked the form sends NOTHING along the post. This means there is no params[:roles] that exists and therefore I get "undefined method `has_key?' for nil:NilClass" because params[:rails] doesnt exist. I've put in checks for whether params[:rails] exists and tried to build it manually but im pretty noob to rails and i failed miserably. Any suggestions? – Bill Garrison Mar 11 '13 at 20:35
  • 1
    I've updated the answer and added `params[:roles] = {} unless params.has_key?(:roles)` at the top of the `update_multiple` controller action. That should fix the problem :) – Sam Mar 11 '13 at 20:40
1

Add this as an answer as request from the OP:

There is a railscast on habtm with checkboxes you may be able to adapt it for your needs: railscasts.com/episodes/17-habtm-checkboxes

DickieBoy
  • 4,886
  • 1
  • 28
  • 47
  • This railscast definitely gave me the first step in the right direction...and before Sam's response would have definately been marked as the answer. Still a very good link to check out if you were in my situation! – Bill Garrison Mar 12 '13 at 13:54