aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb76
1 files changed, 19 insertions, 57 deletions
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index 7e5a8728ee..dab8b75b5c 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -58,41 +58,22 @@ module ActiveRecord
@alias_tracker.aliased_name_for(base.table_name) # Updates the count for base.table_name to 1
tree = self.class.make_tree associations
build tree, @join_root, Arel::InnerJoin
- apply_tables! @join_root
+ @join_root.children.each { |child| construct_tables! @join_root, child }
end
def reflections
join_root.drop(1).map!(&:reflection)
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
- apply_tables! @join_root
- end
-
- def apply_tables!(node)
- node.children.each { |child| construct_tables! node, child }
- end
-
def join_constraints(outer_joins)
- joins = make_joins join_root
+ joins = make_inner_joins join_root
joins.concat outer_joins.flat_map { |oj|
if join_root.match? oj.join_root
walk join_root, oj.join_root
else
oj.join_root.children.flat_map { |child|
- make_the_joins(join_root, child)
+ make_outer_joins(join_root, child)
}
end
}
@@ -173,24 +154,25 @@ module ActiveRecord
private
- def make_the_joins(parent, child)
+ def make_constraints(parent, child, tables, join_type)
chain = child.reflection.chain
foreign_table = parent.table
foreign_klass = parent.base_klass
- tables = table_aliases_for(parent, child)
- join_type = Arel::OuterJoin
+ child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, child.reflection.scope_chain, chain)
+ end
+
+ def make_outer_joins(parent, child)
+ tables = table_aliases_for(parent, child)
+ join_type = Arel::OuterJoin
+ joins = make_constraints parent, child, tables, join_type
- joins = child.join_constraints(foreign_table, foreign_klass, child, join_type, tables, child.reflection.scope_chain, chain)
- joins.concat child.children.flat_map { |c| make_the_joins(child, c) }
+ joins.concat child.children.flat_map { |c| make_outer_joins(child, c) }
end
- def make_joins(node)
- node.children.flat_map { |child|
- chain = child.reflection.chain
- foreign_table = node.table
- foreign_klass = node.base_klass
- child.join_constraints(foreign_table, foreign_klass, child, child.join_type, child.tables, child.reflection.scope_chain, chain)
- .concat make_joins(child)
+ def make_inner_joins(parent)
+ parent.children.flat_map { |child|
+ joins = make_constraints(parent, child, child.tables, Arel::InnerJoin)
+ joins.concat make_inner_joins(child)
}
end
@@ -204,7 +186,7 @@ module ActiveRecord
end
def construct_tables!(parent, node)
- node.tables = table_aliases_for(parent, node) unless node.tables
+ node.tables = table_aliases_for(parent, node)
node.children.each { |child| construct_tables! node, child }
end
@@ -219,29 +201,10 @@ module ActiveRecord
[left.children.find { |node2| node1.match? node2 }, node1]
}.partition(&:first)
- ojs = missing.flat_map { |_,n|
- make_the_joins left, n
- }
-
+ ojs = missing.flat_map { |_,n| make_outer_joins left, n }
intersection.flat_map { |l,r| walk l, r }.concat ojs
end
- 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_reflection(klass, name)
klass.reflect_on_association(name) or
raise ConfigurationError, "Association named '#{ name }' was not found on #{ klass.name }; perhaps you misspelled it?"
@@ -263,8 +226,7 @@ module ActiveRecord
raise EagerLoadPolymorphicError.new(reflection)
end
- node = JoinAssociation.new(reflection, join_type)
- node
+ JoinAssociation.new(reflection, join_type)
end
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)