mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Properly append preload / includes args on Merger
Couldn't find other way to get the association name from a given class other than looping through `reflect_on_all_associations` reflections .. Noticed this one while looking at this example: ```ruby class Product < ActiveRecord::Base has_many :variants has_many :translations end class Translation < ActiveRecord::Base belongs_to :product end class Variant < ActiveRecord::Base belongs_to :product end class BugTest < Minitest::Test def test_merge_stuff product = Product.create! name: 'huhu' variant = Variant.create! product_id: product.id Translation.create! locale: 'en', product_id: product.id product_relation = Product.all .preload(:translations) .joins(:translations) .merge(Translation.where(locale: 'en')) .where(name: 'huhu') assert_equal variant, Variant.joins(:product).merge(product_relation).first end end ```
This commit is contained in:
parent
d0a370ec93
commit
a01d164b94
2 changed files with 50 additions and 2 deletions
|
@ -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?
|
||||
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in a new issue