From d2b4e1b1725906f21e551af299480f819706d391 Mon Sep 17 00:00:00 2001 From: Henry Hsu Date: Sat, 17 Jul 2010 11:16:54 -0700 Subject: [PATCH] Fix a bug where eager loading of a :uniq => true has_and_belongs_to_many returns duplicate entries --- .../lib/active_record/association_preload.rb | 3 ++- .../has_and_belongs_to_many_associations_test.rb | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletions(-) diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index c2206dc..6cd1c86 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -189,12 +189,13 @@ module ActiveRecord conditions = "t0.#{reflection.primary_key_name} #{in_or_equals_for_ids(ids)}" conditions << append_conditions(reflection, preload_options) + distinct = "DISTINCT " if options[:uniq] associated_records = reflection.klass.with_exclusive_scope do reflection.klass.find(:all, :conditions => [conditions, ids], :include => options[:include], :joins => "INNER JOIN #{connection.quote_table_name options[:join_table]} t0 ON #{reflection.klass.quoted_table_name}.#{reflection.klass.primary_key} = t0.#{reflection.association_foreign_key}", - :select => "#{options[:select] || table_name+'.*'}, t0.#{reflection.primary_key_name} as the_parent_record_id", + :select => "#{options[:select] || "#{distinct}#{table_name}.*"}, t0.#{reflection.primary_key_name} as the_parent_record_id", :order => options[:order]) end set_association_collection_records(id_to_record_map, reflection.name, associated_records, 'the_parent_record_id') diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb index 5e8b2ca..b55a3f1 100644 --- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb @@ -320,6 +320,21 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase assert_equal 3, project.developers.size end + def test_uniq_option_with_eager_loading + project = projects(:active_record) + project_id = project.id + dev_3 = developers(:dev_3) + + assert_equal 3, project.developers.size + 5.times do + project.developers << dev_3 + end + assert_equal 4, project.developers.size + + project = Project.find(project.id, :include => [:developers]) + assert_equal 4, project.developers.size + end + def test_deleting david = Developer.find(1) active_record = Project.find(1) -- 1.7.1