Skip to content
This repository
Browse code

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
  • Loading branch information...
commit cfbb6eeb4c778c974399c5196e1ecb9cdafca277 1 parent d9a7f86
Aaron Patterson tenderlove authored
57 activerecord/lib/active_record/associations/join_dependency.rb
@@ -97,14 +97,21 @@ def instantiate(result_set)
97 97
98 98 type_caster = result_set.column_type primary_key
99 99
  100 + seen = Hash.new { |h,parent_klass|
  101 + h[parent_klass] = Hash.new { |i,parent_id|
  102 + i[parent_id] = Hash.new { |j,child_klass|
  103 + j[child_klass] = {}
  104 + }
  105 + }
  106 + }
  107 +
100 108 records = result_set.map { |row_hash|
101 109 primary_id = type_caster.type_cast row_hash[primary_key]
102 110 parent = parents[primary_id] ||= join_root.instantiate(row_hash)
103   - construct(parent, join_root, row_hash, result_set)
  111 + construct(parent, join_root, row_hash, result_set, seen)
104 112 parent
105 113 }.uniq
106 114
107   - remove_duplicate_results!(base_klass, records, join_root.children)
108 115 records
109 116 end
110 117
@@ -147,28 +154,6 @@ def deep_copy(parent, node)
147 154 dup
148 155 end
149 156
150   - def remove_duplicate_results!(base, records, associations)
151   - associations.each do |node|
152   - reflection = node.reflection
153   - remove_uniq_by_reflection(reflection, records)
154   -
155   - parent_records = []
156   - records.each do |record|
157   - if descendant = record.send(reflection.name)
158   - if reflection.collection?
159   - parent_records.concat descendant.target.uniq
160   - else
161   - parent_records << descendant
162   - end
163   - end
164   - end
165   -
166   - unless parent_records.empty?
167   - remove_duplicate_results!(reflection.klass, parent_records, node.children)
168   - end
169   - end
170   - end
171   -
172 157 def find_reflection(klass, name)
173 158 klass.reflect_on_association(name) or
174 159 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)
188 173 parent.children << join_association
189 174 end
190 175
191   - def remove_uniq_by_reflection(reflection, records)
192   - if reflection.collection?
193   - records.each { |record| record.send(reflection.name).target.uniq! }
194   - end
195   - end
196   -
197 176 def build_join_association(reflection, parent, join_type)
198 177 reflection.check_validity!
199 178
@@ -206,7 +185,7 @@ def build_join_association(reflection, parent, join_type)
206 185 node
207 186 end
208 187
209   - def construct(ar_parent, parent, row, rs)
  188 + def construct(ar_parent, parent, row, rs, seen)
210 189 primary_key = parent.aliased_primary_key
211 190 type_caster = rs.column_type primary_key
212 191
@@ -219,15 +198,23 @@ def construct(ar_parent, parent, row, rs)
219 198 else
220 199 if ar_parent.association_cache.key?(node.reflection.name)
221 200 model = ar_parent.association(node.reflection.name).target
222   - construct(model, node, row, rs)
  201 + construct(model, node, row, rs, seen)
223 202 next
224 203 end
225 204 end
226 205
227   - next if row[node.aliased_primary_key].nil?
  206 + id = row[node.aliased_primary_key]
  207 + next if id.nil?
  208 +
  209 + model = seen[parent.base_klass][primary_id][node.base_klass][id]
228 210
229   - model = construct_model(ar_parent, node, row)
230   - construct(model, node, row, rs)
  211 + if model
  212 + construct(model, node, row, rs, seen)
  213 + else
  214 + model = construct_model(ar_parent, node, row)
  215 + seen[parent.base_klass][primary_id][node.base_klass][id] = model
  216 + construct(model, node, row, rs, seen)
  217 + end
231 218 end
232 219 end
233 220 end

0 comments on commit cfbb6ee

Please sign in to comment.
Something went wrong with that request. Please try again.