13

How would I go about defining abilities for several devise models?

4

3 回答 3

17

假设您的应用程序有两个独立的 Devise 用户模型,分别称为UserAdmin。这意味着您可以并排使用current_user和之类的方法。current_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 对象(如果可用),并在没有可用时回退到普通用户。

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

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 万岁最新的错误修复和新功能。相同的命名空间,所以它只是 Gemfile 中的一个插入式 gem 替换。

gem 'cancancan', '~> 1.8'
于 2014-05-21T00:49:18.277 回答
3

这对我有用 -

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
于 2012-09-27T02:27:17.883 回答
2

The current user model is passed to the Ability#initialize, so you can just check its class:

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
于 2012-06-18T23:17:05.947 回答