Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

merge JoinDependency as outer joins

Merge JoinDependency objects as outer joins
  • Loading branch information...
commit 223082e588af59cb35108ce2a2d742dcecf72cc6 1 parent d20ccb7
@tenderlove tenderlove authored
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
Please sign in to comment.
Something went wrong with that request. Please try again.