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

This commit is contained in:
Ryan Bates 2010-09-02 14:46:38 -07:00
parent b1fb179aaf
commit 66314a89f8
3 changed files with 30 additions and 6 deletions

View File

@ -117,7 +117,7 @@ module CanCan
# 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 @@ module CanCan
# 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 File

@ -11,6 +11,7 @@ module CanCan
# 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 @@ module CanCan
# 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 @@ module CanCan
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 File

@ -79,8 +79,10 @@ describe CanCan::Ability do
@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 @@ describe CanCan::Ability do
@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