From 6d5b1fdf55611de2a1071c37544933bb588ae88e Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Mon, 14 Dec 2015 09:48:34 -0700 Subject: Perform a more efficient query in `Relation#any?` This was changed in 421c81b, as `exists?` blows up if you are eager loading a polymorphic association, as it'll try to construct a join to that table. The previous change decided to execute a `count` instead, which wouldn't join. Of course, the only time we actually need to perform a join on the eager loaded values (which would perform a left outer join) is if they're being referenced in the where clause. This doesn't affect inner joins. --- activerecord/lib/active_record/relation.rb | 7 +------ activerecord/lib/active_record/relation/finder_methods.rb | 9 +++++++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb index 2cf19c76c5..6728443251 100644 --- a/activerecord/lib/active_record/relation.rb +++ b/activerecord/lib/active_record/relation.rb @@ -271,12 +271,7 @@ module ActiveRecord def empty? return @records.empty? if loaded? - if limit_value == 0 - true - else - c = count(:all) - c.respond_to?(:zero?) ? c.zero? : c.empty? - end + limit_value == 0 || !exists? end # Returns true if there are no records. diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 435cef901b..b83032e2a0 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -280,8 +280,8 @@ module ActiveRecord return false if !conditions - relation = apply_join_dependency(self, construct_join_dependency) - return false if ActiveRecord::NullRelation === relation + relation = apply_join_dependency(self, construct_join_dependency_for_exists) + return false if ActiveRecord::NullRelation === relation || limit_value == 0 relation = relation.except(:select, :order).select(ONE_AS_ONE).limit(1) @@ -359,6 +359,11 @@ module ActiveRecord ActiveRecord::Associations::JoinDependency.new(@klass, including, joins) end + def construct_join_dependency_for_exists + including = (eager_load_values + includes_values) & references_values.map(&:to_sym) + ActiveRecord::Associations::JoinDependency.new(@klass, including, []) + end + def construct_relation_for_association_calculations from = arel.froms.first if Arel::Table === from -- cgit v1.2.3