我想制作一个记录管理系统。系统将有4个不同的用户角色:Admin
,Viewer
,Editor
和Reviewer
。
虽然前两个很容易使用gems实现,例如 cancan 和声明式授权,但其他两个并不是那么简单。
基本上每条新记录都由Admin
创建(只有管理员可以创建新记录),并且应该有自己独立的Editor
和Reviewer
角色。也就是说,可以在不同的记录上为用户分配许多不同的角色,但不为其他记录分配,因此可以为用户分配记录A和C的Editor
角色,但不为其他角色分配等等。
编辑:可以对记录进行更改,并可以访问控制器中的特定方法,例如编辑等。
审稿人:将能够审核(查看对记录所做的更改)并批准或提交评论并拒绝。
查看者:只能查看每条记录的最新批准版本。
是否有任何方法可以处理此类特定于记录的用户角色?
答案 0 :(得分:3)
这可以通过康康宝石和阻挡条件毫不费力地完成。块条件检查对实例的授权。假设您的Record类有一个返回授权编辑器数组的编辑器方法,那么更新Record的cancan能力可能如下所示:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
...
can :update, Record do |record|
record.editors.include?(user)
end
...
end
end
请参阅CanCan维基上的“阻止条件”: https://github.com/ryanb/cancan/wiki/Defining-Abilities
<强>更新强>
根据您的具体需求,存储哪些用户可以通过多种方式访问哪些记录。一种方法可能是创建这样的模型来存储角色分配:
class UserRecordRoles < ActiveRecord::Base
# Has three fields: role, user_id, record_id
attr_accessible :role, :user_id, :record_id
belongs_to :user_id
belongs_to :record_id
end
现在在User和Record模型中创建一个has_many关联,以便可以轻松查询所有角色分配。编辑器方法可能如下所示:
class Record < ActiveRecord::Base
...
has_many :user_record_roles
def editors
# This is rather messy and requires lot's of DB calls...
user_record_roles.where(:role => 'editor').collect {|a| a.user}
# This would be a single DB call but I'm not sure this would work. Maybe someone else can chime in? Would look cleaner with a scope probably.
User.joins(:user_record_roles).where('user_record_roles.role = ?' => 'editor')
end
...
end
当然,有很多方法可以做到这一点,并且根据您的需求而变化很大。我们的想法是CanCan可以在确定授权时与您的模型交谈,这意味着您可以表现出任何您可以梦想的逻辑。希望这有帮助!