Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix to handle MetaWhere and non-MetaWhere conditions correctly. #632

Merged
merged 1 commit into from

2 participants

Anuj Dutta Ryan Bates
Anuj Dutta
Collaborator

Just a bit of the background of the issue.

When there are multiple rules, CanCan does the sensible thing by merging them together. However, if one of the conditions is of type MetaWhere::Column, it fails. MetaWhere is intelligent enough to work with multiple conditions defined in any format whatsoever. So, this fix simply ensures that with multiple rules, where one of them is of type MetaWhere::Column, CanCan doesn't merge them and just pass it on to MetaWhere.

Anuj Dutta
Collaborator

@ryanb: Hey, can you please review? Thanks.

Ryan Bates ryanb merged commit 80a8c39 into from
Mitsuhiro Shibuya mshibuya referenced this pull request from a commit in sferik/rails_admin
Mitsuhiro Shibuya mshibuya Temporarily lock cancan to 1.6.7
because 1.6.8 has a problem with handling of cannot directive, which was brought in by ryanb/cancan#632
30e3cef
Paul Meserve themgt referenced this pull request from a commit in themgt/rails_admin
Mitsuhiro Shibuya mshibuya Temporarily lock cancan to 1.6.7
because 1.6.8 has a problem with handling of cannot directive, which was brought in by ryanb/cancan#632
381f5d6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
7 lib/cancan/model_adapters/active_record_adapter.rb
View
@@ -89,7 +89,12 @@ def database_records
if override_scope
@model_class.scoped.merge(override_scope)
elsif @model_class.respond_to?(:where) && @model_class.respond_to?(:joins)
- @model_class.where(conditions).joins(joins)
+ mergeable_conditions = @rules.select {|rule| rule.unmergeable? }.blank?
+ if mergeable_conditions
+ @model_class.where(conditions).joins(joins)
+ else
+ @model_class.where(*(@rules.map(&:conditions))).joins(joins)
+ end
else
@model_class.scoped(:conditions => conditions, :joins => joins)
end
4 lib/cancan/rule.rb
View
@@ -54,6 +54,10 @@ def conditions_empty?
@conditions == {} || @conditions.nil?
end
+ def unmergeable?
+ @conditions.respond_to?(:keys) && (! @conditions.keys.first.kind_of? Symbol)
+ end
+
def associations_hash(conditions = @conditions)
hash = {}
conditions.map do |name, value|
10 spec/cancan/model_adapters/active_record_adapter_spec.rb
View
@@ -236,6 +236,16 @@
@ability.should_not be_able_to(:read, article2)
end
+ it "should merge MetaWhere and non-MetaWhere conditions" do
+ @ability.can :read, Article, :priority.lt => 2
+ @ability.can :read, Article, :priority => 1
+ article1 = Article.create!(:priority => 1)
+ article2 = Article.create!(:priority => 3)
+ Article.accessible_by(@ability).should == [article1]
+ @ability.should be_able_to(:read, article1)
+ @ability.should_not be_able_to(:read, article2)
+ end
+
it "should match any MetaWhere condition" do
adapter = CanCan::ModelAdapters::ActiveRecordAdapter
article1 = Article.new(:priority => 1, :name => "Hello World")
7 spec/cancan/rule_spec.rb
View
@@ -36,4 +36,11 @@
rule = CanCan::Rule.new(true, :read, Integer, nil, nil)
rule.associations_hash.should == {}
end
+
+ it "should not be mergeable if conditions are not simple hashes" do
+ meta_where = OpenStruct.new(:name => 'metawhere', :column => 'test')
+ @conditions[meta_where] = :bar
+
+ @rule.should be_unmergeable
+ end
end
Something went wrong with that request. Please try again.