Skip to content
Browse files

support arrays being passed to 'can' to specify multiple actions or c…

…lasses - closes #2
  • Loading branch information...
1 parent 4322da9 commit 766fe86a9f3b649aebff7604c9b2de677ddd71c2 @ryanb ryanb committed Nov 17, 2009
Showing with 21 additions and 3 deletions.
  1. +2 −0 CHANGELOG.rdoc
  2. +5 −3 lib/cancan/ability.rb
  3. +14 −0 spec/cancan/ability_spec.rb
View
2 CHANGELOG.rdoc
@@ -1,3 +1,5 @@
+* support arrays being passed to "can" to specify multiple actions or classes - see issue #2
+
* adding "cannot?" method to ability, controller, and view which is inverse of "can?" - see issue #1
* BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' to set up abilities - see issue #4
View
8 lib/cancan/ability.rb
@@ -4,14 +4,16 @@ module Ability
def can?(original_action, target) # TODO this could use some refactoring
(@can_history || []).reverse.each do |can_action, can_target, can_block|
+ can_actions = [can_action].flatten
+ can_targets = [can_target].flatten
possible_actions_for(original_action).each do |action|
- if (can_action == :manage || can_action == action) && (can_target == :all || can_target == target || target.kind_of?(can_target))
+ if (can_actions.include?(:manage) || can_actions.include?(action)) && (can_targets.include?(:all) || can_targets.include?(target) || can_targets.any? { |c| target.kind_of?(c) })
if can_block.nil?
return true
else
block_args = []
- block_args << action if can_action == :manage
- block_args << (target.class == Class ? target : target.class) if can_target == :all
+ block_args << action if can_actions.include?(:manage)
+ block_args << (target.class == Class ? target : target.class) if can_targets.include?(:all)
block_args << (target.class == Class ? nil : target)
return can_block.call(*block_args)
end
View
14 spec/cancan/ability_spec.rb
@@ -85,4 +85,18 @@
it "should offer cannot? method which is simply invert of can?" do
@ability.cannot?(:tie, String).should be_true
end
+
+ it "should be able to specify multiple actions and match any" do
+ @ability.can [:read, :update], :all
+ @ability.can?(:read, 123).should be_true
+ @ability.can?(:update, 123).should be_true
+ @ability.can?(:count, 123).should be_false
+ end
+
+ it "should be able to specify multiple classes and match any" do
+ @ability.can :update, [String, Array]
+ @ability.can?(:update, "foo").should be_true
+ @ability.can?(:update, []).should be_true
+ @ability.can?(:update, 123).should be_false
+ end
end

0 comments on commit 766fe86

Please sign in to comment.
Something went wrong with that request. Please try again.