一个多设置了许多系统的作用是非常直截了当:
class User
has_many :user_roles
has_many :roles, through: :user_roles
def has_role?(role)
roles.where(name: role).any?
end
end
class Role
has_many :user_roles
has_many :users, through: :user_roles
end
class UserRole
belongs_to :role
belongs_to :user
validates_uniqueness_of :role, :user
end
只要确保你的角色和用户创建的UserRole唯一索引:
add_index :user_roles, [:role_id, :user_id], unique: true
最简单并执行经理要求高性能的方法是将一个 mananger_id
列users
和设置自引用一个添加到一对多的关系:
class User
has_many :user_roles
has_many :roles, through: :user_roles
belongs_to :manager, class_name: 'User'
has_many :subordinates, foreign_key: :manager_id, class_name: 'User'
validate :authorize_manager!
def has_role?(role)
roles.where(name: role).any?
end
private
def authorize_manager!
if manager.present?
errors.add(:manager, "does not have manager role") unless manager.has_role?("manager")
end
end
end
另一种方式来做到这一点是使用资源的局部角色。 最好的部分是你没有自己构建它。有一个由社区创建的称为Rolify的优秀宝石,它为您提供了诸如系统等。
它还比以前的系统更灵活,一旦你掌握了它,你可以添加角色到你的域中的任何类型的资源。
class User < ActiveRecord::Base
rolify
resourcify
end
---
the_boss = User.find(1)
bob = User.find_by(name: 'Bob')
# creating roles
the_boss.add_role(:manager) # add a global role
the_boss.add_role(:manager, bob) # add a role scoped to a user instance
# querying roles
bob.has_role?(:manager) # => false
the_boss.has_role?(:manager) # => true
the_boss.has_role?(:manager, bob) # => true
the_boss.has_role?(:manager, User.create) # => false
如果你去Rolify与授权库,如权威人士或CanCanCan执行这些规则恭维。
来源
2016-03-23 03:13:23
max
我不应该编辑'users'表,但如果另一个选项添加另一个gem,也许一个新的列并不是一个坏主意。 – StorymasterQ
我想我要用'manager_id'列。如何获取新插入的管理员的错误消息名称?编辑:没关系,我想出了'manager.name'。 – StorymasterQ
“添加另一颗宝石”并不总是一件坏事。不要因为担心技术部门或不在这里发明综合症而重新发明轮子。 – max