diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2015-05-28 01:52:14 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2015-05-28 01:52:14 -0300 |
commit | 7cc9754209c0ae00d70bdd629fa4a81a1c74cc6f (patch) | |
tree | 0205c87c305afffd9876c676f23526fe23a6e9c3 | |
parent | be18476fb24ef21a956e79143b6bcde3ec744a64 (diff) | |
parent | a01d164b948371c3405635713d9361f67d10a8bf (diff) | |
download | rails-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.rb | 24 | ||||
-rw-r--r-- | activerecord/test/cases/relations_test.rb | 28 |
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 } |