Shouldn't
if user.role?(x)
can :manage, Post
end
if user.role?(y)
can :manage, Article
end
be enough?
cannot
just removes previously granted permissions. But if you do not grant them, then you do not need to remove them.
See also https://github.com/CanCanCommunity/cancancan/wiki/Ability-Precedence
Here is a running example:
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)
The default is to NOT HAVE a permission. So if you only work in "additive" mode where you add permissions if a user has roles, you will never need to remove one of them.
:manage
is the same as [:create, :edit, :update, :new, :destroy, :index, :show]
and is only there for convenience. If you only want to add 6 of those permissions, you can add all 7 and then remove 1. But other than that I don't think you'll need cannot
for your example.
elsif
on the second to better establish precedence? It may be that the first or last call sticks, so the order might not be clear at a glance. – tadman