Browse files

merge JoinDependency as outer joins

Merge JoinDependency objects as outer joins
  • Loading branch information...
1 parent d20ccb7 commit 223082e588af59cb35108ce2a2d742dcecf72cc6 @tenderlove tenderlove committed Oct 10, 2013
View
30 activerecord/lib/active_record/associations/join_dependency.rb
@@ -85,6 +85,20 @@ def outer_joins
nodes
end
+ def merge_outer_joins!(other)
+ left = join_root
+ right = other.join_root
+
+ if left.match? right
+ merge_node left, right
+ else
+ # If the roots aren't the same, then deep copy the RHS to the LHS
+ left.children.concat right.children.map { |node|
+ deep_copy left, node
+ }
+ end
+ end
+
def join_constraints
join_root.flat_map(&:join_constraints)
end
@@ -118,6 +132,22 @@ def instantiate(result_set)
private
+ def merge_node(left, right)
+ intersection, missing = right.children.map { |node1|
+ [left.children.find { |node2| node1.match? node2 }, node1]
+ }.partition(&:first)
+
+ intersection.each { |l,r| merge_node l, r }
+
+ left.children.concat missing.map { |_,node| deep_copy left, node }
+ end
+
+ def deep_copy(parent, node)
+ dup = build_join_association(node.reflection, parent, Arel::OuterJoin)
+ dup.children.concat node.children.map { |n| deep_copy dup, n }
+ dup
+ end
+
def find_node(target_node)
stack = target_node.parents << target_node
View
2 activerecord/lib/active_record/relation/query_methods.rb
@@ -951,7 +951,7 @@ def build_joins(manager, joins)
)
stashed_association_joins.each do |dep|
- join_dependency.graft dep.outer_joins
+ join_dependency.merge_outer_joins! dep
end
joins = join_dependency.join_constraints

0 comments on commit 223082e

Please sign in to comment.