Skip to content

Commit

Permalink
Associations: speedup duplicate record check. Closes #10011.
Browse files Browse the repository at this point in the history
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8051 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
jeremy committed Oct 29, 2007
1 parent c708346 commit 204c275
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
2 changes: 2 additions & 0 deletions 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]
Expand Down
29 changes: 28 additions & 1 deletion activerecord/lib/active_record/associations.rb
Expand Up @@ -1402,9 +1402,36 @@ def instantiate(rows)
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
Expand Down Expand Up @@ -1461,7 +1488,7 @@ def construct_association(record, join, row)

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?
Expand Down

0 comments on commit 204c275

Please sign in to comment.