aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMehmet Emin INAC <mehmetemininac@gmail.com>2018-01-15 12:03:38 +0100
committerMehmet Emin INAC <mehmetemininac@gmail.com>2018-01-15 16:06:00 +0100
commit899a8014135b1486c693e924fe0e0d6040bf0663 (patch)
treefbb847627b713f25a46abf6f897b27ecea7b54b8
parent562dd0494a90d9d47849f052e8913f0050f3e494 (diff)
downloadrails-899a8014135b1486c693e924fe0e0d6040bf0663.tar.gz
rails-899a8014135b1486c693e924fe0e0d6040bf0663.tar.bz2
rails-899a8014135b1486c693e924fe0e0d6040bf0663.zip
Fix relation merger issue with `left_outer_joins`
-rw-r--r--activerecord/CHANGELOG.md4
-rw-r--r--activerecord/lib/active_record/relation/merger.rb26
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb2
-rw-r--r--activerecord/test/cases/relation/merging_test.rb6
4 files changed, 37 insertions, 1 deletions
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