mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix through association with source/through scope which has joins
If source/through scope references other tables in where/order, we should explicitly maintain joins in the scope, otherwise association queries will fail with referenced unknown column. Fixes #33525.
This commit is contained in:
parent
e4b6c719cd
commit
6a617cc61e
7 changed files with 30 additions and 2 deletions
|
@ -134,6 +134,12 @@ module ActiveRecord
|
|||
|
||||
if scope_chain_item == chain_head.scope
|
||||
scope.merge! item.except(:where, :includes, :unscope, :order)
|
||||
elsif !item.references_values.empty?
|
||||
join_dependency = item.construct_join_dependency(
|
||||
item.eager_load_values | item.includes_values, Arel::Nodes::OuterJoin
|
||||
)
|
||||
scope.joins!(*item.joins_values, join_dependency)
|
||||
scope.left_outer_joins!(*item.left_outer_joins_values)
|
||||
end
|
||||
|
||||
reflection.all_includes do
|
||||
|
|
|
@ -33,6 +33,13 @@ module ActiveRecord
|
|||
|
||||
join_scope = reflection.join_scope(table, foreign_table, foreign_klass)
|
||||
|
||||
unless join_scope.references_values.empty?
|
||||
join_dependency = join_scope.construct_join_dependency(
|
||||
join_scope.eager_load_values | join_scope.includes_values, Arel::Nodes::OuterJoin
|
||||
)
|
||||
join_scope.joins!(join_dependency)
|
||||
end
|
||||
|
||||
arel = join_scope.arel(alias_tracker.aliases)
|
||||
nodes = arel.constraints.first
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ module ActiveRecord
|
|||
reflection.chain.drop(1).each do |reflection|
|
||||
relation = reflection.klass.scope_for_association
|
||||
scope.merge!(
|
||||
relation.except(:select, :create_with, :includes, :preload, :joins, :eager_load)
|
||||
relation.except(:select, :create_with, :includes, :preload, :eager_load, :joins, :left_outer_joins)
|
||||
)
|
||||
end
|
||||
scope
|
||||
|
|
|
@ -380,7 +380,7 @@ module ActiveRecord
|
|||
|
||||
def apply_join_dependency(eager_loading: group_values.empty?)
|
||||
join_dependency = construct_join_dependency(
|
||||
eager_load_values + includes_values, Arel::Nodes::OuterJoin
|
||||
eager_load_values | includes_values, Arel::Nodes::OuterJoin
|
||||
)
|
||||
relation = except(:includes, :eager_load, :preload).joins!(join_dependency)
|
||||
|
||||
|
|
|
@ -1057,10 +1057,18 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|||
|
||||
def test_has_many_through_with_source_scope
|
||||
expected = [readers(:michael_welcome).becomes(LazyReader)]
|
||||
assert_equal expected, Author.first.lazy_readers_skimmers_or_not
|
||||
assert_equal expected, Author.preload(:lazy_readers_skimmers_or_not).first.lazy_readers_skimmers_or_not
|
||||
assert_equal expected, Author.eager_load(:lazy_readers_skimmers_or_not).first.lazy_readers_skimmers_or_not
|
||||
end
|
||||
|
||||
def test_has_many_through_with_join_scope
|
||||
expected = [readers(:bob_welcome).becomes(LazyReader)]
|
||||
assert_equal expected, Author.last.lazy_readers_skimmers_or_not_2
|
||||
assert_equal expected, Author.preload(:lazy_readers_skimmers_or_not_2).last.lazy_readers_skimmers_or_not_2
|
||||
assert_equal expected, Author.eager_load(:lazy_readers_skimmers_or_not_2).last.lazy_readers_skimmers_or_not_2
|
||||
end
|
||||
|
||||
def test_has_many_through_polymorphic_with_rewhere
|
||||
post = TaggedPost.create!(title: "Tagged", body: "Post")
|
||||
tag = post.tags.create!(name: "Tag")
|
||||
|
|
6
activerecord/test/fixtures/readers.yml
vendored
6
activerecord/test/fixtures/readers.yml
vendored
|
@ -9,3 +9,9 @@ michael_authorless:
|
|||
post_id: 3
|
||||
person_id: 1
|
||||
first_post_id: 3
|
||||
|
||||
bob_welcome:
|
||||
id: 3
|
||||
post_id: 8
|
||||
person_id: 4
|
||||
first_post_id: 10
|
||||
|
|
|
@ -177,6 +177,7 @@ class Author < ActiveRecord::Base
|
|||
has_many :topics, primary_key: "name", foreign_key: "author_name"
|
||||
|
||||
has_many :lazy_readers_skimmers_or_not, through: :posts
|
||||
has_many :lazy_readers_skimmers_or_not_2, through: :posts_with_no_comments, source: :lazy_readers_skimmers_or_not
|
||||
|
||||
attr_accessor :post_log
|
||||
after_initialize :set_post_log
|
||||
|
|
Loading…
Reference in a new issue