cancan
cancan copied to clipboard
Ability issue with block definition
Using CanCan 1.6.10 and Rails 4, I stumbled over a weird issue.
Short example:
# ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new(role: 'user')
can :read, Group do |group|
user.group_memberships.where(group_id: group.id).exists?
end
can :manage, Group do |group|
user.group_memberships.where(group_id: group.id, role: 'admin').exists?
end
end
end
# weirdo spec
it 'wtfs' do
ability = Ability.new(nil)
expect(ability).not_to be_able_to(:manage, Group) # this will fail
end
I didn't expect the ability to be able to manage Group
. Am I missing something or is this seriously broken?
Repo for you right here.
Update: It's not that bad, easy to fix it seems. See https://github.com/ryanb/cancan/blob/440bd887008820efbee8b954790f79b48d8264a6/lib/cancan/rule.rb#L33-L34.
# ability.rb
can :read, Group { |group| ... }
# application
can? :read, Group # => true
To "fix" this, add the following:
elsif @block && !subject_class?(subject)
@block.call(subject, *extra_args)
elsif @block && subject_class?(subject)
false
Question: Am I still missing something or is the behaviour I desire not intended?
For now, I'll use a fork: https://github.com/tbuehlmann/cancan/tree/hotfix/block_definition.
Thanks for your submission! The ryanb/cancan repository has been inactive since Sep 06, 2013. Since only Ryan himself has commit permissions, the CanCan project is on a standstill.
CanCan has many open issues, including missing support for Rails 4. To keep CanCan alive, an active fork exists at cancancommunity/cancancan. The new gem is cancancan. More info is available at #994.
If your pull request or issue is still applicable, it would be really appreciated if you resubmit it to CanCanCan.
We hope to see you on the other side!
Yeah, no, I replaced CanCan with Pundit long ago and I'm happy ever after. Thanks for the hint though. I'll let this Issue open since I don't know the actual code and whether or not this is still a thing.