Skip to content
This repository
Browse code

construct joins by walking the outer join tree

  • Loading branch information...
commit 7894ae39c8313d83d64d5a058470ec1ef4ed22e1 1 parent 796c0fc
Aaron Patterson tenderlove authored
39 activerecord/lib/active_record/associations/join_dependency.rb
@@ -85,8 +85,22 @@ def apply_tables!(node)
85 85 end
86 86
87 87 def join_constraints(outer_joins)
88   - outer_joins.each { |oj| merge_outer_joins! oj }
89   - make_joins join_root
  88 + if outer_joins.any?
  89 + oj = outer_joins.first
  90 +
  91 + if join_root.match? oj.join_root
  92 + outer_joins.each { |oj| merge_outer_joins! oj }
  93 + make_joins join_root
  94 + else
  95 + make_joins(join_root) + outer_joins.flat_map { |join|
  96 + join.join_root.children.flat_map { |child|
  97 + make_the_joins(join_root, child)
  98 + }
  99 + }
  100 + end
  101 + else
  102 + make_joins join_root
  103 + end
90 104 end
91 105
92 106 class Aliases
@@ -164,6 +178,17 @@ def instantiate(result_set, aliases)
164 178
165 179 private
166 180
  181 + def make_the_joins(parent, child)
  182 + chain = child.reflection.chain
  183 + foreign_table = parent.table
  184 + foreign_klass = parent.base_klass
  185 + tables = table_aliases_for(parent, child)
  186 + join_type = Arel::OuterJoin
  187 +
  188 + joins = child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, child.reflection.scope_chain, chain)
  189 + joins.concat child.children.flat_map { |c| make_the_joins(child, c) }
  190 + end
  191 +
167 192 def make_joins(node)
168 193 node.children.flat_map { |child|
169 194 chain = child.reflection.chain
@@ -174,13 +199,17 @@ def make_joins(node)
174 199 }
175 200 end
176 201
177   - def construct_tables!(parent, node)
178   - node.tables = node.reflection.chain.map { |reflection|
  202 + def table_aliases_for(parent, node)
  203 + node.reflection.chain.map { |reflection|
179 204 alias_tracker.aliased_table_for(
180 205 reflection.table_name,
181 206 table_alias_for(reflection, parent, reflection != node.reflection)
182 207 )
183   - } unless node.tables
  208 + }
  209 + end
  210 +
  211 + def construct_tables!(parent, node)
  212 + node.tables = table_aliases_for(parent, node) unless node.tables
184 213 node.children.each { |child| construct_tables! node, child }
185 214 end
186 215

0 comments on commit 7894ae3

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