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

use*_*499 12 ruby-on-rails devise cancan

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

Fra*_*ehl 13

假设您的应用程序有两个独立的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
Run Code Online (Sandbox Code Playgroud)

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

默认情况下,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
Run Code Online (Sandbox Code Playgroud)

现在,我们的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
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅Wiki中的更改默认值.荣誉对斯特凡在适当文章指着我.

仅供参考 - CanCan死了,CanCanCan万岁!最新的错误修复和新功能.相同的命名空间,因此它只是Gemfile中的一个直接替换宝石.

gem 'cancancan', '~> 1.8'
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 2

当前的用户模型被传递给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
Run Code Online (Sandbox Code Playgroud)