Today I faced the same needs and found a way to do this on the CanCan Wiki .
Just follow these simple steps:
1) Create a constant under the User class with role names:
class User < ActiveRecord::Base ROLES = %w[admin moderator author banned] end
2a) Create and run the migration if you are using ActiveRecord:
rails generate migration add_roles_mask_to_users roles_mask:integer rake db:migrate
2b) Add this field to the user model if you are using Mongoid:
field :roles_mask, type: Integer
3) Then you need to add the following code to the user model:
# in models/user.rb def roles=(roles) self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.inject(0, :+) end def roles ROLES.reject do |r| ((roles_mask.to_i || 0) & 2**ROLES.index(r)).zero? end end
4) If you use the application without strong parameters, be sure to add attr_accessible: roles to the user model. If you use devise with strong_parameters, either as a stone in a Rails 3 application or as a built-in in Rails 4, be sure to add roles to the allowed list in the controller:
class ApplicationController < ActionController::Base before_filter :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:email, :password, :password_confirmation, roles: [])} end end
5) Add the code below to create checkboxes in the view to set these roles:
<% for role in User::ROLES %> <%= check_box_tag "user[roles][#{role}]", role, @user.roles.include?(role), {:name => "user[roles][]"}%> <%= label_tag "user_roles_#{role}", role.humanize %><br /> <% end %> <%= hidden_field_tag "user[roles][]", "" %>
6) Finally, you can add a convenient way to test user roles in the Ability class:
# in models/user.rb def is?(role) roles.include?(role.to_s) end # in models/ability.rb can :manage, :all if user.is? :admin
What is it.
Hope this helps.