From b7d1c6dc0e69d6e893016ad44a65e4463b9e2cfd Mon Sep 17 00:00:00 2001 From: Matt Glover Date: Sat, 7 Dec 2013 17:21:23 -0500 Subject: [PATCH] Do not execute the scope condition on class permission checks. @conditions.empty? calls ActiveRecord::Relation#empty? when a scoped condition is provided. ActiveRecord::Relation#empty? will query the database while CanCan only needs to check if conditions are set on the rule. --- lib/cancan/rule.rb | 2 +- .../model_adapters/active_record_adapter_spec.rb | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/cancan/rule.rb b/lib/cancan/rule.rb index c0415de8..422c49d0 100644 --- a/lib/cancan/rule.rb +++ b/lib/cancan/rule.rb @@ -38,7 +38,7 @@ def matches_conditions?(action, subject, extra_args) matches_conditions_hash?(subject) else # Don't stop at "cannot" definitions when there are conditions. - @conditions.empty? ? true : @base_behavior + conditions_empty? ? true : @base_behavior end end diff --git a/spec/cancan/model_adapters/active_record_adapter_spec.rb b/spec/cancan/model_adapters/active_record_adapter_spec.rb index a51774c4..786e7d35 100644 --- a/spec/cancan/model_adapters/active_record_adapter_spec.rb +++ b/spec/cancan/model_adapters/active_record_adapter_spec.rb @@ -316,5 +316,17 @@ # adapter.matches_condition?(article1, :name.nlike, "%helo%").should be_true # adapter.matches_condition?(article1, :name.nlike, "%ello worl%").should be_false end + + it 'should not execute a scope when checking ability on the class' do + relation = Article.where(:secret => true) + @ability.can :read, Article, relation do |article| + article.secret == true + end + + # Ensure the ActiveRecord::Relation condition does not trigger a count query + stub(relation).count { fail 'Unexpected scope execution.' } + + expect { @ability.can? :read, Article }.not_to raise_error + end end end