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

时间:2012-06-18 18:25:45

标签: ruby-on-rails devise cancan

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

3 个答案:

答案 0 :(得分: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

这正是其他人提出的建议,但你必须采取另一个步骤。

默认情况下,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对象(如果有),如果没有,则返回普通用户。

进一步开发允许我们将管理员权限移动到他们自己独立的Ability类......

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

有关详细信息,请参阅Wiki中的Changing Defaults。感谢Stefan向我指出正确的文章。

仅供参考 - CanCan已经死了,现场直播CanCanCan最新的错误修复和新功能。相同的命名空间,所以它只是Gemfile中的一个直接替换宝石。

gem 'cancancan', '~> 1.8'

答案 1 :(得分: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

答案 2 :(得分:2)

这对我有用 -

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