diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2007-10-29 03:02:42 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2007-10-29 03:02:42 +0000 |
commit | 204c2755e2531c5c35077949fbc90e3cb1788b9c (patch) | |
tree | cb2d21660c0ae012e9eb39806413a0068ac0f5cb /activerecord | |
parent | c708346688ee3cdd5583795ccd9b10590abd36b1 (diff) | |
download | rails-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')
-rw-r--r-- | activerecord/CHANGELOG | 2 | ||||
-rwxr-xr-x | activerecord/lib/active_record/associations.rb | 29 |
2 files changed, 30 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG b/activerecord/CHANGELOG index d9b4b8cbf5..a7f8ad522e 100644 --- a/activerecord/CHANGELOG +++ b/activerecord/CHANGELOG @@ -1,5 +1,7 @@ *SVN* +* Associations: speedup duplicate record check. #10011 [lifofifo] + * Make sure that << works on has_many associations on unsaved records. Closes #9989 [hasmanyjosh] * Allow association redefinition in subclasses. #9346 [wildchild] 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? |