1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix n+1 query problem when eager loading nil associations (fixes #18312)

This commit is contained in:
Sammy Larbi 2015-01-03 13:30:30 -06:00
parent 02e72a49d1
commit c840b18ac3
3 changed files with 18 additions and 1 deletions

View file

@ -1,3 +1,7 @@
* Fix n+1 query problem when eager loading nil associations (fixes #18312)
*Sammy Larbi*
* Clear query cache on rollback. * Clear query cache on rollback.
*Florian Weingarten* *Florian Weingarten*

View file

@ -232,6 +232,7 @@ module ActiveRecord
end end
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases) def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
return if ar_parent.nil?
primary_id = ar_parent.id primary_id = ar_parent.id
parent.children.each do |node| parent.children.each do |node|
@ -248,7 +249,11 @@ module ActiveRecord
key = aliases.column_alias(node, node.primary_key) key = aliases.column_alias(node, node.primary_key)
id = row[key] id = row[key]
next if id.nil? if id.nil?
nil_association = ar_parent.association(node.reflection.name)
nil_association.loaded!
next
end
model = seen[parent.base_klass][primary_id][node.base_klass][id] model = seen[parent.base_klass][primary_id][node.base_klass][id]

View file

@ -77,9 +77,17 @@ class EagerAssociationTest < ActiveRecord::TestCase
def test_has_many_through_with_order def test_has_many_through_with_order
authors = Author.includes(:favorite_authors).to_a authors = Author.includes(:favorite_authors).to_a
assert authors.count > 0
assert_no_queries { authors.map(&:favorite_authors) } assert_no_queries { authors.map(&:favorite_authors) }
end end
def test_eager_loaded_has_one_association_with_references_does_not_run_additional_queries
Post.update_all(author_id: nil)
authors = Author.includes(:post).references(:post).to_a
assert authors.count > 0
assert_no_queries { authors.map(&:post) }
end
def test_with_two_tables_in_from_without_getting_double_quoted def test_with_two_tables_in_from_without_getting_double_quoted
posts = Post.select("posts.*").from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").order("posts.id").to_a posts = Post.select("posts.*").from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").order("posts.id").to_a
assert_equal 2, posts.first.comments.size assert_equal 2, posts.first.comments.size