aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Mendonça França <rafaelmfranca@gmail.com>2015-05-28 01:52:14 -0300
committerRafael Mendonça França <rafaelmfranca@gmail.com>2015-05-28 01:52:14 -0300
commit7cc9754209c0ae00d70bdd629fa4a81a1c74cc6f (patch)
tree0205c87c305afffd9876c676f23526fe23a6e9c3
parentbe18476fb24ef21a956e79143b6bcde3ec744a64 (diff)
parenta01d164b948371c3405635713d9361f67d10a8bf (diff)
downloadrails-7cc9754209c0ae00d70bdd629fa4a81a1c74cc6f.tar.gz
rails-7cc9754209c0ae00d70bdd629fa4a81a1c74cc6f.tar.bz2
rails-7cc9754209c0ae00d70bdd629fa4a81a1c74cc6f.zip
Merge pull request #20196 from huoxito/preload-association-and-merges
Properly append preload / includes args on Merger
-rw-r--r--activerecord/lib/active_record/relation/merger.rb24
-rw-r--r--activerecord/test/cases/relations_test.rb28
2 files changed, 50 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/relation/merger.rb b/activerecord/lib/active_record/relation/merger.rb
index c3054f1fe9..01c05462b2 100644
--- a/activerecord/lib/active_record/relation/merger.rb
+++ b/activerecord/lib/active_record/relation/merger.rb
@@ -50,7 +50,7 @@ module ActiveRecord
NORMAL_VALUES = Relation::VALUE_METHODS -
Relation::CLAUSE_METHODS -
- [:joins, :order, :reverse_order, :lock, :create_with, :reordering] # :nodoc:
+ [:includes, :preload, :joins, :order, :reverse_order, :lock, :create_with, :reordering] # :nodoc:
def normal_values
NORMAL_VALUES
@@ -75,6 +75,7 @@ module ActiveRecord
merge_multi_values
merge_single_values
merge_clauses
+ merge_preloads
merge_joins
relation
@@ -82,6 +83,27 @@ module ActiveRecord
private
+ def merge_preloads
+ return if other.preload_values.empty? && other.includes_values.empty?
+
+ if other.klass == relation.klass
+ relation.preload! other.preload_values unless other.preload_values.empty?
+ relation.includes! other.includes_values unless other.includes_values.empty?
+ else
+ reflection = relation.klass.reflect_on_all_associations.find do |reflection|
+ reflection.class_name == other.klass.name
+ end || return
+
+ unless other.preload_values.empty?
+ relation.preload! reflection.name => other.preload_values
+ end
+
+ unless other.includes_values.empty?
+ relation.includes! reflection.name => other.includes_values
+ end
+ end
+ end
+
def merge_joins
return if other.joins_values.blank?
diff --git a/activerecord/test/cases/relations_test.rb b/activerecord/test/cases/relations_test.rb
index a4ca3ab637..acbf85d398 100644
--- a/activerecord/test/cases/relations_test.rb
+++ b/activerecord/test/cases/relations_test.rb
@@ -17,7 +17,7 @@ require 'models/tyre'
require 'models/minivan'
require 'models/aircraft'
require "models/possession"
-
+require "models/reader"
class RelationTest < ActiveRecord::TestCase
fixtures :authors, :topics, :entrants, :developers, :companies, :developers_projects, :accounts, :categories, :categorizations, :posts, :comments,
@@ -621,6 +621,32 @@ class RelationTest < ActiveRecord::TestCase
assert_equal 1, query.to_a.size
end
+ def test_preloading_with_associations_and_merges
+ post = Post.create! title: 'Uhuu', body: 'body'
+ reader = Reader.create! post_id: post.id, person_id: 1
+ comment = Comment.create! post_id: post.id, body: 'body'
+
+ assert !comment.respond_to?(:readers)
+
+ post_rel = Post.preload(:readers).joins(:readers).where(title: 'Uhuu')
+ result_comment = Comment.joins(:post).merge(post_rel).to_a.first
+ assert_equal comment, result_comment
+
+ assert_no_queries do
+ assert_equal post, result_comment.post
+ assert_equal [reader], result_comment.post.readers.to_a
+ end
+
+ post_rel = Post.includes(:readers).where(title: 'Uhuu')
+ result_comment = Comment.joins(:post).merge(post_rel).first
+ assert_equal comment, result_comment
+
+ assert_no_queries do
+ assert_equal post, result_comment.post
+ assert_equal [reader], result_comment.post.readers.to_a
+ end
+ end
+
def test_loading_with_one_association
posts = Post.preload(:comments)
post = posts.find { |p| p.id == 1 }