aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2007-10-29 03:02:42 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2007-10-29 03:02:42 +0000
commit204c2755e2531c5c35077949fbc90e3cb1788b9c (patch)
treecb2d21660c0ae012e9eb39806413a0068ac0f5cb /activerecord/lib/active_record
parentc708346688ee3cdd5583795ccd9b10590abd36b1 (diff)
downloadrails-204c2755e2531c5c35077949fbc90e3cb1788b9c.tar.gz
rails-204c2755e2531c5c35077949fbc90e3cb1788b9c.tar.bz2
rails-204c2755e2531c5c35077949fbc90e3cb1788b9c.zip
Associations: speedup duplicate record check. Closes #10011.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8051 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record')
-rwxr-xr-xactiverecord/lib/active_record/associations.rb29
1 files changed, 28 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 654b24d71c..f4369060f7 100755
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1402,9 +1402,36 @@ module ActiveRecord
end
construct(@base_records_hash[primary_id], @associations, join_associations.dup, row)
end
+ remove_duplicate_results!(join_base.active_record, @base_records_in_order, @associations)
return @base_records_in_order
end
+ def remove_duplicate_results!(base, records, associations)
+ case associations
+ when Symbol, String
+ reflection = base.reflections[associations]
+ if reflection && [:has_many, :has_and_belongs_to_many].include?(reflection.macro)
+ records.each { |record| record.send(reflection.name).target.uniq! }
+ end
+ when Array
+ associations.each do |association|
+ remove_duplicate_results!(base, records, association)
+ end
+ when Hash
+ associations.keys.each do |name|
+ reflection = base.reflections[name]
+ is_collection = [:has_many, :has_and_belongs_to_many].include?(reflection.macro)
+
+ parent_records = records.map do |record|
+ next unless record.send(reflection.name)
+ is_collection ? record.send(reflection.name).target.uniq! : record.send(reflection.name)
+ end.flatten.compact
+
+ remove_duplicate_results!(reflection.class_name.constantize, parent_records, associations[name]) unless parent_records.empty?
+ end
+ end
+ end
+
def aliased_table_names_for(table_name)
joins.select{|join| join.table_name == table_name }.collect{|join| join.aliased_table_name}
end
@@ -1461,7 +1488,7 @@ module ActiveRecord
return nil if record.id.to_s != join.parent.record_id(row).to_s or row[join.aliased_primary_key].nil?
association = join.instantiate(row)
- collection.target.push(association) unless collection.target.include?(association)
+ collection.target.push(association)
when :has_one
return if record.id.to_s != join.parent.record_id(row).to_s
association = join.instantiate(row) unless row[join.aliased_primary_key].nil?