Rails可以为多个设计模型提供能力类

yre*_*uta 10 ruby-on-rails devise cancan ruby-on-rails-3 activeadmin

我想知道如何定义一个能力等级并根据已登录的用户提供该能力等级.

我正在使用Active Admin,Can Can和Devise,我已成功创建了User和AdminUser模型.

我的能力就是这个.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if (user)
      can :manage, Item
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

现在我已经使用这个wiki条目来确定我们确实可以定义一个自定义能力文件并使用它而不是ability.rb:

https://github.com/ryanb/cancan/wiki/changing-defaults

但我想要做的是,如果登录了"非管理员用户",则能够使用ability.rb;如果登录用户管理员,则能够使用自定义能力.

问题:是否可以这样做,我不需要自定义的,我可以在一个ability.rb文件中设置权限?

And*_*dev 12

我从来没有真正使用过ActiveAdmin,所以我不完全确定我是否遗漏了某些内容,但似乎该框架并不依赖于CanCan.这就是为什么我假设你正在定义一个current_ability像在wiki中解释的方法并且它被实例化了Ability.new(current_user).

如果是这种情况,并且您current_user可以是a User或a AdminUser,那么在Ability类中检查它是没有问题的:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if user.kind_of? AdminUser
      can :manage, Item
    elsif user.kind_of? User
      can :read, Item
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

您只需查看用户的类型并相应地更改规则即可.您也可以使用is_a?而不是kind_of?更严格的检查,但它可能不是必需的,如果您决定稍后继承,可能会导致问题.

您可以检查的另一种方法是admin?在两个模型中定义方法.这可能是一种更好的方法,因为显式类型检查在ruby中不是很受欢迎 - 它通常会限制您的选择.它可能看起来像这样:

class User < ActiveRecord::Base
  def admin?
    false
  end
end

class AdminUser < ActiveRecord::Base
  def admin?
    true
  end
end

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    if user.admin?
      can :manage, Item
    else
      can :read, Item
    end
  end
end
Run Code Online (Sandbox Code Playgroud)