supporting arrays, ranges, and nested hashes in ability conditions

This commit is contained in:
Ryan Bates 2010-04-17 11:54:27 -07:00
parent 283f58ee16
commit f1ba76b61b
3 changed files with 36 additions and 3 deletions

View File

@ -1,5 +1,7 @@
1.1.0 (not released)
* Supporting arrays, ranges, and nested hashes in ability conditions
* Removing "unauthorized!" method in favor of "authorize!" in controllers
* Adding action, subject and default_message abilities to AccessDenied exception - see issue #40

View File

@ -244,15 +244,26 @@ module CanCan
if subject.class == Class
true
else
defined_conditions.all? do |name, value|
subject.send(name) == value
end
matches_conditions? subject, defined_conditions
end
else
true
end
end
def matches_conditions?(subject, defined_conditions)
defined_conditions.all? do |name, value|
attribute = subject.send(name)
if value.kind_of?(Hash)
matches_conditions? attribute, value
elsif value.kind_of?(Array) || value.kind_of?(Range)
value.include? attribute
else
attribute == value
end
end
end
def includes_action?(actions, action)
actions.include?(:manage) || actions.include?(action)
end

View File

@ -148,6 +148,26 @@ describe CanCan::Ability do
@ability.can?(:read, Array).should be_true
end
it "should allow an array of options in conditions hash" do
@ability.can :read, Array, :first => [1, 3, 5]
@ability.can?(:read, [1, 2, 3]).should be_true
@ability.can?(:read, [2, 3]).should be_false
@ability.can?(:read, [3, 4]).should be_true
end
it "should allow a range of options in conditions hash" do
@ability.can :read, Array, :first => 1..3
@ability.can?(:read, [1, 2, 3]).should be_true
@ability.can?(:read, [3, 4]).should be_true
@ability.can?(:read, [4, 5]).should be_false
end
it "should allow nested hashes in conditions hash" do
@ability.can :read, Array, :first => { :length => 5 }
@ability.can?(:read, ["foo", "bar"]).should be_false
@ability.can?(:read, ["test1", "foo"]).should be_true
end
it "should return conditions for a given ability" do
@ability.can :read, Array, :first => 1, :last => 3
@ability.conditions(:show, Array).should == {:first => 1, :last => 3}