From 5ea8e528bf3fbb80fc18de76e108f09b87bbc7e6 Mon Sep 17 00:00:00 2001 From: Ryuta Kamizono Date: Sat, 2 Sep 2017 15:42:35 +0900 Subject: Fix preloading through association with custom scope If `reflection_scope.where_clause` is not empty, `through_scope` should be joined the source association. But if `values[:references]` in `reflection_scope` is empty, the source association will not be joined. It should use `source_reflection.table_name` in that case. Fixes #22535. Closes #28763. --- .../active_record/associations/preloader/through_association.rb | 7 ++++++- activerecord/test/cases/associations/eager_test.rb | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb index b469a9ca10..f0a2e88c53 100644 --- a/activerecord/lib/active_record/associations/preloader/through_association.rb +++ b/activerecord/lib/active_record/associations/preloader/through_association.rb @@ -94,6 +94,12 @@ module ActiveRecord scope.includes!(source_reflection.name) end + if values[:references] && !values[:references].empty? + scope.references!(values[:references]) + else + scope.references!(source_reflection.table_name) + end + if joins = values[:joins] scope.joins!(source_reflection.name => joins) end @@ -102,7 +108,6 @@ module ActiveRecord scope.left_outer_joins!(source_reflection.name => left_outer_joins) end - scope.references! values[:references] if scope.eager_loading? && order_values = values[:order] scope = scope.order(order_values) end diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb index 9fb395853e..3fd2c73efc 100644 --- a/activerecord/test/cases/associations/eager_test.rb +++ b/activerecord/test/cases/associations/eager_test.rb @@ -1307,6 +1307,11 @@ class EagerAssociationTest < ActiveRecord::TestCase assert_equal projects.last.mentor.developers.first.contracts, projects.last.developers.last.contracts end + def test_preloading_has_many_through_with_custom_scope + project = Project.includes(:developers_named_david_with_hash_conditions).find(projects(:active_record).id) + assert_equal [developers(:david)], project.developers_named_david_with_hash_conditions + end + test "scoping with a circular preload" do assert_equal Comment.find(1), Comment.preload(post: :comments).scoping { Comment.find(1) } end -- cgit v1.2.3