Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

supporting arrays, ranges, and nested hashes in ability conditions

  • Loading branch information...
commit f1ba76b61bcef5d13b254e98e13aacc577e1bfd7 1 parent 283f58e
@ryanb ryanb authored
View
2  CHANGELOG.rdoc
@@ -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
17 lib/cancan/ability.rb
@@ -244,15 +244,26 @@ def can_perform_action?(action, subject, defined_actions, defined_subjects, defi
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
20 spec/cancan/ability_spec.rb
@@ -148,6 +148,26 @@
@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}
Please sign in to comment.
Something went wrong with that request. Please try again.