我在一个项目中使用CanCan来管理每个项目的每个实体的不同角色级别。 我这样做:
# encoding: utf-8
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
if user.is_admin == true
can :manage, :all
else
can :read, :all
Project.all.each do |project|
current_role_name = user.roles.find_by_project_id(project.id).role_name.name
if current_role_name.eql?'Auteur senior'
can :manage, [Project, Introduction, Abstract, Text, Conclusion, Asset, Attachment], :project_id => project.id
elsif current_role_name.eql?'Auteur junior'
can :manage, [Introduction, Abstract, Attachment], :project_id => project.id
can :update, Text, :project_id => project.id, :user_level => current_role_name
can :manage, [Asset], :project_id => project.id, :user_level => current_role_name
elsif current_role_name.eql?'Équipe phylogéniste'
can :manage, [Attachment], :project_id => project.id
can :manage, [Text, Asset], :project_id => project.id, :user_level => current_role_name
end
end
end
end
end
当我检查用户role_name但在我想要使用这样的条件之后,它会起作用:
can :update, Text, :project_id => project.id, :user_level => current_role_name
条件没有任何影响。我怎样才能使它发挥作用?
答案 0 :(得分:1)
我用得做的是:
1-在我的用户类中定义角色并将其影响到用户。
class User
# CanCan roles ( see Users::Ability)
ROLES = %w[auteur_senior auteur_junior]
def roles=(roles)
self.roles_mask = (roles & ROLES).map { |r| 2**ROLES.index(r) }.sum
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
# define all bollean set/get methods for roles
ROLES.each do |r|
define_method "is_#{r}" do
self.roles += [r]
self
end
define_method "is_#{r}?" do
roles.include?(r)
self
end
end
end
2 - 我能够影响每个角色的能力
class Ability
include CanCan::Ability
def initialize(user)
@user = user || User.new # for guest
@user.roles.each { |role| send(role) }
end
def auteur_junior
can :manage, [Introduction, Abstract, Attachment], :project_id => project.id
can :update, Text, :project_id => project.id, :user_level => current_role_name
can :manage, [Asset], :project_id => project.id, :user_level => current_role_name
end
def auteur_scenior
can :manage, [Project, Introduction, Abstract, Text, Conclusion, Asset, Attachment], :project_id => project.id
end
end
答案 1 :(得分:1)
我终于找到了解决方案:
在相关的控制器中,我用load_and_authorize_resource替换了authorize_resource,就是这样。
答案 2 :(得分:0)
authorize_resource
方法在类上调用authorize!
,除非它传递了一个实例。在不使用load_resource
或load_and_authorize_resource
的情况下,您将nil传递给authorize_resource
before_filter。
Example from the CanCan documentation:
#authorize_resource(*args) ⇒ Object
authorize!(params[:action].to_sym, @article || Article)
如果您想使用自己的方法(而不是CanCan的load_resource
)从数据库加载记录并拥有更多控制权,那么您可以创建自己的方法,如load_thing
,并使用{{ 1}}。 这会在调用prepend_before_filter :load_thing
之前将记录加载到实例变量中,确保实例变量不是nil,并检查能力文件中指定的规则。