Skip to content

Commit abcbfe8

Browse files
authored
Merge pull request rails#39378 from kamipo/fix_has_many_through_with_source_scope
Fix through association to respect source scope for `includes`/`preload`
2 parents 7e2de5a + 489df7e commit abcbfe8

File tree

4 files changed

+14
-4
lines changed

4 files changed

+14
-4
lines changed

Diff for: activerecord/lib/active_record/associations/preloader/association.rb

+4-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ def scope
132132
end
133133

134134
def reflection_scope
135-
@reflection_scope ||= reflection.scope ? reflection.scope_for(klass.unscoped) : klass.unscoped
135+
@reflection_scope ||= begin
136+
reflection.join_scopes(klass.arel_table, klass.predicate_builder).inject(klass.unscoped, &:merge!)
137+
end
136138
end
137139

138140
def build_scope
@@ -142,7 +144,7 @@ def build_scope
142144
scope.where!(reflection.type => model.polymorphic_name)
143145
end
144146

145-
scope.merge!(reflection_scope) if reflection.scope
147+
scope.merge!(reflection_scope) unless reflection_scope.empty_scope?
146148

147149
if preload_scope && !preload_scope.empty_scope?
148150
scope.merge!(preload_scope)

Diff for: activerecord/test/cases/associations/has_many_through_associations_test.rb

+6
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,12 @@ def test_can_update_through_association
10551055
end
10561056
end
10571057

1058+
def test_has_many_through_with_source_scope
1059+
expected = [readers(:michael_welcome).becomes(LazyReader)]
1060+
assert_equal expected, Author.preload(:lazy_readers_skimmers_or_not).first.lazy_readers_skimmers_or_not
1061+
assert_equal expected, Author.eager_load(:lazy_readers_skimmers_or_not).first.lazy_readers_skimmers_or_not
1062+
end
1063+
10581064
def test_has_many_through_polymorphic_with_rewhere
10591065
post = TaggedPost.create!(title: "Tagged", body: "Post")
10601066
tag = post.tags.create!(name: "Tag")

Diff for: activerecord/test/cases/associations/nested_through_associations_test.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ def test_nested_has_many_through_with_conditions_on_through_associations
517517
def test_nested_has_many_through_with_conditions_on_through_associations_preload
518518
assert_empty Author.where("tags.id" => 100).joins(:misc_post_first_blue_tags)
519519

520-
author = assert_queries(3) { Author.includes(:misc_post_first_blue_tags).third }
520+
author = assert_queries(2) { Author.includes(:misc_post_first_blue_tags).third }
521521
blue = tags(:blue)
522522

523523
assert_no_queries do
@@ -538,7 +538,7 @@ def test_nested_has_many_through_with_conditions_on_source_associations
538538
end
539539

540540
def test_nested_has_many_through_with_conditions_on_source_associations_preload
541-
author = assert_queries(4) { Author.includes(:misc_post_first_blue_tags_2).third }
541+
author = assert_queries(2) { Author.includes(:misc_post_first_blue_tags_2).third }
542542
blue = tags(:blue)
543543

544544
assert_no_queries do

Diff for: activerecord/test/models/author.rb

+2
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ def extension_method; end
176176

177177
has_many :topics, primary_key: "name", foreign_key: "author_name"
178178

179+
has_many :lazy_readers_skimmers_or_not, through: :posts
180+
179181
attr_accessor :post_log
180182
after_initialize :set_post_log
181183

0 commit comments

Comments
 (0)