[gem] Rolify
# Gemfile
# Very simple Roles library without any authorization enforcement supporting scope on resource objects (instance or class). Supports ActiveRecord and Mongoid ORMs.
gem 'rolify', '~> 5.2'
- rolify - usage @ Github WIki
- rolify - configuration @ Github Wiki
- rolify @ Github
設定
$ rails g rolify Role User
$ rails db:migrate
若使用的 id 是 uuid,則在 migrate 檔中記得要作對應的修改:
# db/migrate/20180619081033_rolify_create_roles.rb
class RolifyCreateRoles < ActiveRecord::Migration[5.2]
def change
create_table :roles, id: :uuid do |t|
t.string :name
t.references :resource, :polymorphic => true, type: :uuid
t.timestamps
end
create_table(:users_roles, :id => false) do |t|
t.references :user, type: :uuid
t.references :role, type: :uuid
end
add_index(:roles, [ :name, :resource_type, :resource_id ])
add_index(:users_roles, [ :user_id, :role_id ])
end
end
如果角色需要 scope 在某個 model 底下
假設 Event 底下會有許多不同的 roles:
# app/models/event.rb
class Event < ActiveRecord::Base
resourcify
end
新增刪除角色
新增角色(role)的時候, 角色可以被定義在 Global, Class 或 Instance 這幾個不同層級:
# define GLOBAL role
user.add_role :admin
# define a role scope for specific CLASS resource
user.add_role :admin, Organization
# define a role scope for specific INSTANCE resource
user.add_role :organization_manager, Organization.first
# remove a role 刪除的時候可以不用指定 instance
user.remove_role :moderator
角色查詢
instance method
回傳 true 或 false:
user.has_role? :admin # 如果當初角色是定義在 Global
user.has_role? :admin, Organization # 如果當初角色是定義在 Class
user.has_role? :admin, Organization.first # 如果當初角色是定義在 Instance
user.has_role? :admin, :any # 不管當初角色定義在哪一個 scope
user.roles_name.include? 'admin' # 不管當初角色定義在哪一個 scope,效能可能較好
# user.has_all_roles? 是否具有所有列出的角色
user.has_all_roles? :admin, {name: :event_member, resource: event}
# user.has_any_role? 是否具有所列的其中一種角色
user.has_any_role? (:admin, {name: :event_member, resource: event})
# user.only_has_role? 是否只具有這個角色
user.only_has_role? :admin