diff --git a/lib/cancan/model_adapters/active_record_adapter.rb b/lib/cancan/model_adapters/active_record_adapter.rb index a98cae2..f20da17 100644 --- a/lib/cancan/model_adapters/active_record_adapter.rb +++ b/lib/cancan/model_adapters/active_record_adapter.rb @@ -89,7 +89,12 @@ module CanCan 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 diff --git a/lib/cancan/rule.rb b/lib/cancan/rule.rb index 081079c..82758ba 100644 --- a/lib/cancan/rule.rb +++ b/lib/cancan/rule.rb @@ -54,6 +54,10 @@ module CanCan @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| diff --git a/spec/cancan/model_adapters/active_record_adapter_spec.rb b/spec/cancan/model_adapters/active_record_adapter_spec.rb index 0c82c02..a9debdd 100644 --- a/spec/cancan/model_adapters/active_record_adapter_spec.rb +++ b/spec/cancan/model_adapters/active_record_adapter_spec.rb @@ -236,6 +236,16 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record" @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") diff --git a/spec/cancan/rule_spec.rb b/spec/cancan/rule_spec.rb index ca2464e..42f67af 100644 --- a/spec/cancan/rule_spec.rb +++ b/spec/cancan/rule_spec.rb @@ -36,4 +36,11 @@ describe CanCan::Rule do 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