提交 cfbb6eeb 编写于 作者: A Aaron Patterson

keep track of AR objects we've made as we walk the tree

Remove duplicate removal code because we avoid adding duplicates as we
walk the tree the first time
上级 d9a7f866
......@@ -97,14 +97,21 @@ def instantiate(result_set)
type_caster = result_set.column_type primary_key
seen = Hash.new { |h,parent_klass|
h[parent_klass] = Hash.new { |i,parent_id|
i[parent_id] = Hash.new { |j,child_klass|
j[child_klass] = {}
}
}
}
records = result_set.map { |row_hash|
primary_id = type_caster.type_cast row_hash[primary_key]
parent = parents[primary_id] ||= join_root.instantiate(row_hash)
construct(parent, join_root, row_hash, result_set)
construct(parent, join_root, row_hash, result_set, seen)
parent
}.uniq
remove_duplicate_results!(base_klass, records, join_root.children)
records
end
......@@ -147,28 +154,6 @@ def deep_copy(parent, node)
dup
end
def remove_duplicate_results!(base, records, associations)
associations.each do |node|
reflection = node.reflection
remove_uniq_by_reflection(reflection, records)
parent_records = []
records.each do |record|
if descendant = record.send(reflection.name)
if reflection.collection?
parent_records.concat descendant.target.uniq
else
parent_records << descendant
end
end
end
unless parent_records.empty?
remove_duplicate_results!(reflection.klass, parent_records, node.children)
end
end
end
def find_reflection(klass, name)
klass.reflect_on_association(name) or
raise ConfigurationError, "Association named '#{ name }' was not found on #{ klass.name }; perhaps you misspelled it?"
......@@ -188,12 +173,6 @@ def build_scalar(reflection, parent, join_type)
parent.children << join_association
end
def remove_uniq_by_reflection(reflection, records)
if reflection.collection?
records.each { |record| record.send(reflection.name).target.uniq! }
end
end
def build_join_association(reflection, parent, join_type)
reflection.check_validity!
......@@ -206,7 +185,7 @@ def build_join_association(reflection, parent, join_type)
node
end
def construct(ar_parent, parent, row, rs)
def construct(ar_parent, parent, row, rs, seen)
primary_key = parent.aliased_primary_key
type_caster = rs.column_type primary_key
......@@ -219,15 +198,23 @@ def construct(ar_parent, parent, row, rs)
else
if ar_parent.association_cache.key?(node.reflection.name)
model = ar_parent.association(node.reflection.name).target
construct(model, node, row, rs)
construct(model, node, row, rs, seen)
next
end
end
next if row[node.aliased_primary_key].nil?
id = row[node.aliased_primary_key]
next if id.nil?
model = seen[parent.base_klass][primary_id][node.base_klass][id]
model = construct_model(ar_parent, node, row)
construct(model, node, row, rs)
if model
construct(model, node, row, rs, seen)
else
model = construct_model(ar_parent, node, row)
seen[parent.base_klass][primary_id][node.base_klass][id] = model
construct(model, node, row, rs, seen)
end
end
end
end
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册