如何将CanCan与多种设计模型集成?

我将如何定义几个设计模型的能力?

假设您的应用程序有两个独立的Devise驱动的用户模型,称为UserAdmin 。 这意味着您并排使用current_usercurrent_admin等方法。

让我们进一步假设你只有/想要一个Ability类,其中包含你所有的CanCan权限设置……

 class Ability include CanCan::Ability def initialize(user) user ||= User.new case user when User can :create, Comment can :read, :all when Admin can :manage, :all end end end 

这正是其他人提出的建议,但还有另一个步骤。

默认情况下,CanCan假定方法current_user存在,并将返回User对象以与Ability设置进行比较。 但是,我们的管理员用户可以使用current_admin找到。 在不告诉CanCan在哪里找到管理对象的情况下,他们永远不会得到审核,因此永远不会获得权限; 我们必须在处理管理员时更改默认值。

将以下内容添加到application_controller.rb

 def current_ability if admin_signed_in? @current_ability ||= Ability.new(current_admin) else @current_ability ||= Ability.new(current_user) end end 

现在,我们的Ability类将查看Admin对象(如果有),并且当没有可用时返回普通用户。

进一步的开发允许我们将Admin权限移动到他们自己独立的Ability类中……

 def current_ability if admin_signed_in? @current_ability ||= AdminPowers.new(current_admin) else @current_ability ||= Ability.new(current_user) end end 

有关更多信息,请参阅Wiki中的更改默认值 。 感谢Stefan指出我正确的文章。

仅供参考 – CanCan死了, CanCanCan万岁 ! 最新的错误修复和新function。 相同的命名空间,所以它只是Gemfile中的一个替代gem替代品。

 gem 'cancancan', '~> 1.8' 

当前用户模型将传递给Ability#initialize ,因此您只需检查其类:

 class Ability include CanCan::Ability def initialize(model) case model when Admin can :manage, :all when User can :create, Comment can :read, :all else can :read, :all end end end 

这对我有用 –

 class Ability include CanCan::Ability def initialize(user) if user.is_a?(Admin) can :manage, :all elsif user.is_a?(User) can :create, Comment can :read, :all else can :read, :all end end end