From 4b455e4f32b7bc39bc43b607c0044684d452b9b2 Mon Sep 17 00:00:00 2001 From: sinsoku Date: Sun, 13 Oct 2019 03:18:39 +0900 Subject: [PATCH] Fix an issue with duplicate preloaded records Fixes #37446 --- .../lib/active_record/associations/preloader.rb | 2 +- .../cases/associations/cascaded_eager_loading_test.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/activerecord/lib/active_record/associations/preloader.rb b/activerecord/lib/active_record/associations/preloader.rb index d4e8b364e1..5bba945202 100644 --- a/activerecord/lib/active_record/associations/preloader.rb +++ b/activerecord/lib/active_record/associations/preloader.rb @@ -111,7 +111,7 @@ module ActiveRecord association.flat_map { |parent, child| grouped_records(parent, records, polymorphic_parent).flat_map do |reflection, reflection_records| loaders = preloaders_for_reflection(reflection, reflection_records, scope) - recs = loaders.flat_map(&:preloaded_records) + recs = loaders.flat_map(&:preloaded_records).uniq child_polymorphic_parent = reflection && reflection.options[:polymorphic] loaders.concat Array.wrap(child).flat_map { |assoc| preloaders_on assoc, recs, scope, child_polymorphic_parent diff --git a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb index cbe48a374f..e3850a422c 100644 --- a/activerecord/test/cases/associations/cascaded_eager_loading_test.rb +++ b/activerecord/test/cases/associations/cascaded_eager_loading_test.rb @@ -190,4 +190,15 @@ class CascadedEagerLoadingTest < ActiveRecord::TestCase assert_equal 3, authors[1].posts.size assert_equal 3, authors[0].posts.collect { |post| post.categorizations.size }.inject(0) { |sum, i| sum + i } end + + # Regression test for https://github.com/rails/rails/issues/37446 + def test_preloaded_records_are_not_duplicated + author = Author.first + expected = Post.where(author: author) + .includes(author: :first_posts).map { |post| post.author.first_posts.size } + actual = author.posts + .includes(author: :first_posts).map { |post| post.author.first_posts.size } + + assert_equal expected, actual + end end