Last active
March 19, 2016 20:18
-
-
Save developer88/5007569 to your computer and use it in GitHub Desktop.
This is my gist that show how we can use CanCan with ActiveAdmin and store permissions in database.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/active_admin.rb | |
ActiveAdmin.setup do |config| | |
config.current_user_method = :current_user | |
config.authentication_method = :authenticate_user! | |
config.before_filter :admin_role_filter | |
end | |
# Adding all recource names to Permissions table after ActiveAdmin is loaded | |
ActiveAdmin.after_load do |app| | |
# check if Permission table exists | |
if ActiveRecord::Base.connection.table_exists? 'permissions' | |
app.namespaces.each do |name, namespace| | |
namespace.resources.each do |resource| | |
next if resource.class.name.demodulize == 'Page' | |
resource_name = resource.resource_class_name.demodulize.underscore | |
Permission.create(name: resource_name) unless Permission.where(:name => resource_name).any? | |
end | |
end | |
end | |
end | |
ActiveAdmin::ResourceController.class_eval do | |
protected | |
def current_ability | |
@current_ability ||= AdminAbility.new(current_user) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/admin_ability.rb | |
# All back end users (i.e. Active Admin users) are authorized using this class | |
class AdminAbility | |
include CanCan::Ability | |
def initialize(user) | |
user ||= User.new | |
# restrict abilities to every user | |
cannot :manage, :all | |
cannot :read, :all | |
cannot :edit, :all | |
# check ability stored in database | |
if user.is? :admin | |
can do |action, subject_class, subject| | |
user.as_admin_can?(subject_class) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/application_controller.rb | |
class ApplicationController < ActionController::Base | |
def admin_role_filter | |
unless current_user.is?(:admin) | |
return redirect_to root_url | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permissation.rb | |
class Permissation < ActiveRecord::Base | |
belongs_to :user | |
belongs_to :permission | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/permission.rb | |
class Permission < ActiveRecord::Base | |
has_many :permissations | |
has_many :users, through: :permissations | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# db/migrate/123456789_create_permissions_table.rb | |
class CreatePermissionsTable < ActiveRecord::Migration | |
def up | |
# Create table | |
create_table :permissations do |t| | |
t.integer :user_id | |
t.integer :permission_id | |
end | |
create_table :permissions do |t| | |
t.string :name | |
t.timestamps | |
end | |
# Create necessary permissions | |
%w{permission user}.each {|p| Permission.create(name: p)} | |
# By default give these permissions to everyone with 'admin' role | |
User.find_each(:batch_size => 5000) do |user| | |
next unless user.is? :admin | |
user.permissions << Permission.find_by_name('permission') | |
user.permissions << Permission.find_by_name('user') | |
user.save | |
end | |
end | |
def down | |
drop_table :permissions | |
drop_table :permissations | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
class User < ActiveRecord::Base | |
ROLES = %w[admin manager editor] | |
has_many :permissions, through: :permissations | |
accepts_nested_attributes_for :permissions | |
attr_accessible :permission_ids | |
# check user's permission for ActiveAdmin | |
def as_admin_can? obj | |
permissions.where(:name => obj.to_s.underscore).count > 0 | |
end | |
def roles | |
ROLES.reject do |r| | |
((roles_mask || 0) & 2 ** ROLES.index(r)).zero? | |
end | |
end | |
def is?(role) | |
roles.include?(role.to_s) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# any ActiveAdmin Resource | |
# app/admin/users.rb | |
ActiveAdmin.register User do | |
controller.authorize_resource | |
menu :parent => proc{ I18n.t("active_admin.menu.users") }, :if => proc{ current_user.as_admin_can?(User) } | |
index do | |
if current_user.as_admin_can? 'permission' | |
column I18n.t("activerecord.models.permission") do |user| | |
user.permissions.collect {|p| p.name.camelize }.join(", ") | |
end | |
end | |
end | |
form do |f| | |
if current_user.as_admin_can? 'permission' | |
f.inputs I18n.t("activerecord.models.permission") do | |
f.input :permissions, :as => :check_boxes, :collection => f.object.permissions | Permission.all | |
end | |
end | |
f.actions | |
end | |
end |
Can you post a full working example App using this feature?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi! Where you get role_mask?