From 899a8014135b1486c693e924fe0e0d6040bf0663 Mon Sep 17 00:00:00 2001 From: Mehmet Emin INAC Date: Mon, 15 Jan 2018 12:03:38 +0100 Subject: Fix relation merger issue with `left_outer_joins` --- activerecord/CHANGELOG.md | 4 ++++ activerecord/lib/active_record/relation/merger.rb | 26 +++++++++++++++++++++- .../lib/active_record/relation/query_methods.rb | 2 ++ activerecord/test/cases/relation/merging_test.rb | 6 +++++ 4 files changed, 37 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 9f1ca768a0..efe555374a 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,7 @@ +* Fix relation merger issue with `left_outer_joins`. + + *Mehmet Emin İNAÇ* + * Don't allow destroyed object mutation after `save` or `save!` is called. *Ryuta Kamizono* diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb index b736b21525..ebdd4144bb 100644 --- a/activerecord/lib/active_record/relation/merger.rb +++ b/activerecord/lib/active_record/relation/merger.rb @@ -52,7 +52,7 @@ module ActiveRecord NORMAL_VALUES = Relation::VALUE_METHODS - Relation::CLAUSE_METHODS - - [:includes, :preload, :joins, :order, :reverse_order, :lock, :create_with, :reordering] # :nodoc: + [:includes, :preload, :joins, :left_outer_joins, :order, :reverse_order, :lock, :create_with, :reordering] # :nodoc: def normal_values NORMAL_VALUES @@ -79,6 +79,7 @@ module ActiveRecord merge_clauses merge_preloads merge_joins + merge_outer_joins relation end @@ -129,6 +130,29 @@ module ActiveRecord end end + def merge_outer_joins + return if other.left_outer_joins_values.blank? + + if other.klass == relation.klass + relation.left_outer_joins!(*other.left_outer_joins_values) + else + alias_tracker = nil + joins_dependency = other.left_outer_joins_values.map do |join| + case join + when Hash, Symbol, Array + alias_tracker ||= other.alias_tracker + ActiveRecord::Associations::JoinDependency.new( + other.klass, other.table, join, alias_tracker + ) + else + join + end + end + + relation.left_outer_joins!(*joins_dependency) + end + end + def merge_multi_values if other.reordering_value # override any order specified in the original relation diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb index 0f02096593..86882c7ce7 100644 --- a/activerecord/lib/active_record/relation/query_methods.rb +++ b/activerecord/lib/active_record/relation/query_methods.rb @@ -979,6 +979,8 @@ module ActiveRecord case join when Hash, Symbol, Array :association_join + when ActiveRecord::Associations::JoinDependency + :stashed_join else raise ArgumentError, "only Hash, Symbol and Array are allowed" end diff --git a/activerecord/test/cases/relation/merging_test.rb b/activerecord/test/cases/relation/merging_test.rb index b68b3723f6..f31df40c91 100644 --- a/activerecord/test/cases/relation/merging_test.rb +++ b/activerecord/test/cases/relation/merging_test.rb @@ -72,6 +72,12 @@ class RelationMergingTest < ActiveRecord::TestCase assert_equal 1, comments.count end + def test_relation_merging_with_left_outer_joins + comments = Comment.joins(:post).where(body: "Thank you for the welcome").merge(Post.left_outer_joins(:author).where(body: "Such a lovely day")) + + assert_equal 1, comments.count + end + def test_relation_merging_with_association assert_queries(2) do # one for loading post, and another one merged query post = Post.where(body: "Such a lovely day").first -- cgit v1.2.3