Permalink
Browse files

Exists shouldn't error when used with `includes`

Currently `exists?` does some hackery where it assumes that we can join
onto anything that we passed to `eager_load` or `includes`, which
doesn't work if we are joining onto a polymorphic association.

Actually figuring out if we want to include something would require
knowledge deep within the join dependency module, which is hard to pull
up. The simplest solution is just to pass a flag down that says we're
not actually going to try to eager load any of the data. It's not the
solution I'd like, but that code really needs to be untangled before we
can do much with it.

This is another attempt at 6d5b1fd which should address the concerns
that led to reverting it in 4ecabed.
  • Loading branch information...
sgrif committed May 30, 2016
1 parent 518893f commit 02da8aea832485044fde1b94c021a66d37d54dec
@@ -92,8 +92,9 @@ def self.walk_tree(associations, hash)
# associations # => [:appointments]
# joins # => []
#
def initialize(base, associations, joins)
def initialize(base, associations, joins, eager_loading: true)
@alias_tracker = AliasTracker.create_with_joins(base.connection, base.table_name, joins, base.type_caster)
@eager_loading = eager_loading
tree = self.class.make_tree associations
@join_root = JoinBase.new base, build(tree, base)
@join_root.children.each { |child| construct_tables! @join_root, child }
@@ -238,11 +239,12 @@ def build(associations, base_klass)
reflection.check_eager_loadable!
if reflection.polymorphic?
next unless @eager_loading
raise EagerLoadPolymorphicError.new(reflection)
end
JoinAssociation.new reflection, build(right, reflection.klass)
end
end.compact
end
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
@@ -279,12 +279,7 @@ def size
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.
@@ -318,7 +318,7 @@ def exists?(conditions = :none)
return false if !conditions
relation = apply_join_dependency(self, construct_join_dependency)
relation = apply_join_dependency(self, construct_join_dependency(eager_loading: false))
return false if ActiveRecord::NullRelation === relation
relation = relation.except(:select, :order).select(ONE_AS_ONE).limit(1)
@@ -392,9 +392,9 @@ def find_with_associations
end
end
def construct_join_dependency(joins = [])
def construct_join_dependency(joins = [], eager_loading: true)
including = eager_load_values + includes_values
ActiveRecord::Associations::JoinDependency.new(@klass, including, joins)
ActiveRecord::Associations::JoinDependency.new(@klass, including, joins, eager_loading: eager_loading)
end
def construct_relation_for_association_calculations
@@ -1341,6 +1341,7 @@ def test_eager_load_multiple_associations_with_references
assert_nothing_raised do
authors(:david).essays.includes(:writer).any?
authors(:david).essays.includes(:writer).exists?
end
end

0 comments on commit 02da8ae

Please sign in to comment.