aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/relation
diff options
context:
space:
mode:
authorRyuta Kamizono <kamipo@gmail.com>2019-04-26 20:03:03 +0900
committerRyuta Kamizono <kamipo@gmail.com>2019-04-27 21:43:57 +0900
commit20ede2e2e6e28cf26da4d056cd7638b27d48ed57 (patch)
tree0c8d93b49aa2d2d015f34279316e5bfa7dcb2985 /activerecord/lib/active_record/relation
parentbbc3704bb38d9739d46d94d12a2a854f47b52cbe (diff)
downloadrails-20ede2e2e6e28cf26da4d056cd7638b27d48ed57.tar.gz
rails-20ede2e2e6e28cf26da4d056cd7638b27d48ed57.tar.bz2
rails-20ede2e2e6e28cf26da4d056cd7638b27d48ed57.zip
Fix merging left_joins to maintain its own `join_type` context
This fixes a regression for #35864. Usually, stashed joins (mainly eager loading) are performed as LEFT JOINs. But the case of merging joins/left_joins of different class, that (stashed) joins are performed as the same `join_type` as the parent context for now. Since #35864, both (joins/left_joins) stashed joins might be contained in `joins_values`, so each stashed joins should maintain its own `join_type` context. Fixes #36103.
Diffstat (limited to 'activerecord/lib/active_record/relation')
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb4
-rw-r--r--activerecord/lib/active_record/relation/merger.rb8
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb10
3 files changed, 14 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 9450e4d3c5..9c7ac80447 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -371,7 +371,9 @@ module ActiveRecord
end
def apply_join_dependency(eager_loading: group_values.empty?)
- join_dependency = construct_join_dependency(eager_load_values + includes_values)
+ join_dependency = construct_join_dependency(
+ eager_load_values + includes_values, Arel::Nodes::OuterJoin
+ )
relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
if eager_loading && !using_limitable_reflections?(join_dependency.reflections)
diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb
index 6bb77b355c..84fe424ef0 100644
--- a/activerecord/lib/active_record/relation/merger.rb
+++ b/activerecord/lib/active_record/relation/merger.rb
@@ -123,7 +123,9 @@ module ActiveRecord
end
end
- join_dependency = other.construct_join_dependency(associations)
+ join_dependency = other.construct_join_dependency(
+ associations, Arel::Nodes::InnerJoin
+ )
relation.joins!(join_dependency, *others)
end
end
@@ -135,7 +137,9 @@ module ActiveRecord
relation.left_outer_joins!(*other.left_outer_joins_values)
else
associations = other.left_outer_joins_values
- join_dependency = other.construct_join_dependency(associations)
+ join_dependency = other.construct_join_dependency(
+ associations, Arel::Nodes::OuterJoin
+ )
relation.joins!(join_dependency)
end
end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index c03ca7f1e7..b8fd2fce14 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -1005,9 +1005,9 @@ module ActiveRecord
@arel ||= build_arel(aliases)
end
- def construct_join_dependency(associations) # :nodoc:
+ def construct_join_dependency(associations, join_type) # :nodoc:
ActiveRecord::Associations::JoinDependency.new(
- klass, table, associations
+ klass, table, associations, join_type
)
end
@@ -1102,7 +1102,7 @@ module ActiveRecord
def build_joins(manager, joins, aliases)
unless left_outer_joins_values.empty?
left_joins = valid_association_list(left_outer_joins_values.flatten)
- joins << construct_join_dependency(left_joins)
+ joins.unshift construct_join_dependency(left_joins, Arel::Nodes::OuterJoin)
end
buckets = joins.group_by do |join|
@@ -1134,9 +1134,9 @@ module ActiveRecord
join_list = join_nodes + convert_join_strings_to_ast(string_joins)
alias_tracker = alias_tracker(join_list, aliases)
- join_dependency = construct_join_dependency(association_joins)
+ join_dependency = construct_join_dependency(association_joins, join_type)
- joins = join_dependency.join_constraints(stashed_joins, join_type, alias_tracker)
+ joins = join_dependency.join_constraints(stashed_joins, alias_tracker)
joins.each { |join| manager.from(join) }
manager.join_sources.concat(join_list)