diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb index 4db5c67ad0f..7c23b7fbe26 100644 --- a/activerecord/lib/active_record/associations/preloader/association.rb +++ b/activerecord/lib/active_record/associations/preloader/association.rb @@ -247,8 +247,8 @@ module ActiveRecord association = owner.association(reflection.name) if reflection.collection? - association.loaded! - association.target.concat(records) + not_persisted_records = association.target.reject(&:persisted?) + association.target = records + not_persisted_records else association.target = records.first end diff --git a/activerecord/test/cases/associations_test.rb b/activerecord/test/cases/associations_test.rb index 69c1adfd436..812a6f17030 100644 --- a/activerecord/test/cases/associations_test.rb +++ b/activerecord/test/cases/associations_test.rb @@ -804,6 +804,17 @@ class PreloaderTest < ActiveRecord::TestCase end end + def test_preload_does_not_concatenate_duplicate_records + post = posts(:welcome) + post.reload + post.comments.create!(body: "A new comment") + + ActiveRecord::Associations::Preloader.new(records: [post], associations: :comments).call + + assert_equal post.comments.length, post.comments.count + assert_equal post.comments.all.to_a, post.comments + end + def test_preload_for_hmt_with_conditions post = posts(:welcome) _normal_category = post.categories.create!(name: "Normal")