分配冲突的CanCan角色

时间:2016-10-20 16:53:36

标签: ruby-on-rails ruby cancan

我正在使用CanCan Gem,并希望为用户分配两个冲突的角色。我需要一个User有两个角色,一个是x角色,另一个是y角色。角色x允许用户创建帖子但不能创建文章。角色y允许用户创建文章但不创建帖子。

我的ability.rb文件如下:

if user.role?(x)
  can :manage, Post
  cannot :manage, Article
end
if user.role?(y)
 cannot :manage, Post
 can :manage, Article
end

目前,如果我为用户分配两个角色,则角色Y的权限将覆盖角色x的权限。我想允许管理员堆叠角色,这样如果我想将角色x和y添加到用户,该用户将能够管理帖子和文章。因此,如果角色具有can而另一个角色具有can,则can权限将​​覆盖。

1 个答案:

答案 0 :(得分:1)

不应该

if user.role?(x)
  can :manage, Post
end
if user.role?(y)
  can :manage, Article
end

够了吗? cannot只删除以前授予的权限。但是如果你不批准它们,那么你不需要删除它们。

另见https://github.com/CanCanCommunity/cancancan/wiki/Ability-Precedence

这是一个正在运行的例子:

require 'cancan'

class Ability
  include CanCan::Ability
  attr_reader :user

  def initialize(user)
    @user = user

    if user.role?(:editor)
      can :edit, Post
    end

    if user.role?(:reader)
      can :read, Post
    end
  end
end

class Post
end

class User
  attr_reader :name
  def initialize(name, *roles)
    @name = name
    @roles = roles
  end

  def role?(role)
    @roles.include?(role)
  end
end

admin = User.new('admin', :reader, :editor)
user = User.new('user', :reader)
editor = User.new('editor', :editor)

admin_ability = Ability.new(admin)
user_ability = Ability.new(user)
editor_ability = Ability.new(editor)


def output(ability, permission)
  puts "#{ability.user.name} can #{permission} Post: #{ability.can?(permission, Post)}"
end

output(admin_ability, :edit)
output(user_ability, :edit)
output(editor_ability, :edit)
puts "--"
output(admin_ability, :read)
output(user_ability, :read)
output(editor_ability, :read)

默认是没有权限。所以,如果你只是在"添加剂"如果用户具有角色,您可以在其中添加权限的模式,您将永远不需要删除其中一个。

:manage[:create, :edit, :update, :new, :destroy, :index, :show]相同,仅为方便起见。如果您只想添加其中的6个权限,则可以添加全部7个权限,然后删除1.但除此之外,我认为您不需要cannot作为示例。