Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

support no arguments to 'can' definition which always calls block

  • Loading branch information...
commit 66314a89f863ad825e0e9b7c2ecedae412433b1f 1 parent b1fb179
@ryanb authored
View
4 lib/cancan/ability.rb
@@ -117,7 +117,7 @@ def cannot?(*args)
# can :read, :stats
# can? :read, :stats # => true
#
- def can(action, subject, conditions = nil, &block)
+ def can(action = nil, subject = nil, conditions = nil, &block)
can_definitions << CanDefinition.new(true, action, subject, conditions, block)
end
@@ -133,7 +133,7 @@ def can(action, subject, conditions = nil, &block)
# product.invisible?
# end
#
- def cannot(action, subject, conditions = nil, &block)
+ def cannot(action = nil, subject = nil, conditions = nil, &block)
can_definitions << CanDefinition.new(false, action, subject, conditions, block)
end
View
15 lib/cancan/can_definition.rb
@@ -11,6 +11,7 @@ class CanDefinition # :nodoc:
# and subject respectively (such as :read, @project). The third argument is a hash
# of conditions and the last one is the block passed to the "can" call.
def initialize(base_behavior, action, subject, conditions, block)
+ @match_all = action.nil? && subject.nil?
@base_behavior = base_behavior
@actions = [action].flatten
@subjects = [subject].flatten
@@ -20,12 +21,14 @@ def initialize(base_behavior, action, subject, conditions, block)
# Matches both the subject and action, not necessarily the conditions
def relevant?(action, subject)
- matches_action?(action) && matches_subject?(subject)
+ @match_all || (matches_action?(action) && matches_subject?(subject))
end
# Matches the block or conditions hash
def matches_conditions?(action, subject, extra_args)
- if @block && subject.class != Class
+ if @match_all
+ call_block_with_all(action, subject, extra_args)
+ elsif @block && subject.class != Class
@block.call(subject, *extra_args)
elsif @conditions.kind_of?(Hash) && subject.class != Class
matches_conditions_hash?(subject)
@@ -91,5 +94,13 @@ def matches_conditions_hash?(subject, conditions = @conditions)
end
end
end
+
+ def call_block_with_all(action, subject, extra_args)
+ if subject.class == Class
+ @block.call(action, subject, nil, *extra_args)
+ else
+ @block.call(action, subject.class, subject, *extra_args)
+ end
+ end
end
end
View
17 spec/cancan/ability_spec.rb
@@ -79,8 +79,10 @@
@ability.can?(:increment, 123).should be_true
end
- it "should return block result and only pass object for any action" do
- @ability.can :manage, :all do |object|
+ it "should always call block with arguments when passing no arguments to can" do
+ @ability.can do |action, object_class, object|
+ action.should == :foo
+ object_class.should == 123.class
object.should == 123
@block_called = true
end
@@ -88,6 +90,17 @@
@block_called.should be_true
end
+ it "should pass nil to object when comparing class with can check" do
+ @ability.can do |action, object_class, object|
+ action.should == :foo
+ object_class.should == Hash
+ object.should be_nil
+ @block_called = true
+ end
+ @ability.can?(:foo, Hash)
+ @block_called.should be_true
+ end
+
it "should automatically alias index and show into read calls" do
@ability.can :read, :all
@ability.can?(:index, 123).should be_true
Please sign in to comment.
Something went wrong with that request. Please try again.