diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index d111d00bc9..9a0350d452 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -183,20 +183,22 @@ module ActiveRecord scope_chain_items = join_scopes(table, predicate_builder) klass_scope = klass_join_scope(table, predicate_builder) + if type + klass_scope.where!(type => foreign_klass.polymorphic_name) + end + + scope_chain_items.inject(klass_scope, &:merge!) + key = join_keys.key foreign_key = join_keys.foreign_key klass_scope.where!(table[key].eq(foreign_table[foreign_key])) - if type - klass_scope.where!(type => foreign_klass.polymorphic_name) - end - if klass.finder_needs_type_condition? klass_scope.where!(klass.send(:type_condition, table)) end - scope_chain_items.inject(klass_scope, &:merge!) + klass_scope end def join_scopes(table, predicate_builder) # :nodoc: diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 57b18b8d21..daccd95729 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -2658,10 +2658,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal [bulb1], car.bulbs assert_equal [bulb1, bulb2], car.all_bulbs.sort_by(&:id) + assert_equal [bulb1, bulb2], Car.includes(:all_bulbs).find(car.id).all_bulbs.sort_by(&:id) + assert_equal [bulb1, bulb2], Car.eager_load(:all_bulbs).find(car.id).all_bulbs.sort_by(&:id) end test "can unscope and where the default scope of the associated model" do - Car.has_many :other_bulbs, -> { unscope(where: [:name]).where(name: "other") }, class_name: "Bulb" car = Car.create! bulb1 = Bulb.create! name: "defaulty", car: car bulb2 = Bulb.create! name: "other", car: car @@ -2671,7 +2672,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase end test "can rewhere the default scope of the associated model" do - Car.has_many :old_bulbs, -> { rewhere(name: "old") }, class_name: "Bulb" car = Car.create! bulb1 = Bulb.create! name: "defaulty", car: car bulb2 = Bulb.create! name: "old", car: car @@ -2682,11 +2682,11 @@ class HasManyAssociationsTest < ActiveRecord::TestCase test "unscopes the default scope of associated model when used with include" do car = Car.create! - bulb = Bulb.create! name: "other", car: car + bulb1 = Bulb.create! name: "defaulty", car: car + bulb2 = Bulb.create! name: "other", car: car - assert_equal [bulb], Car.find(car.id).all_bulbs - assert_equal [bulb], Car.includes(:all_bulbs).find(car.id).all_bulbs - assert_equal [bulb], Car.eager_load(:all_bulbs).find(car.id).all_bulbs + assert_equal [bulb1, bulb2], Car.includes(:all_bulbs2).find(car.id).all_bulbs2.sort_by(&:id) + assert_equal [bulb1, bulb2], Car.eager_load(:all_bulbs2).find(car.id).all_bulbs2.sort_by(&:id) end test "raises RecordNotDestroyed when replaced child can't be destroyed" do diff --git a/activerecord/test/models/car.rb b/activerecord/test/models/car.rb index 8614926626..e1f989dad2 100644 --- a/activerecord/test/models/car.rb +++ b/activerecord/test/models/car.rb @@ -2,7 +2,10 @@ class Car < ActiveRecord::Base has_many :bulbs - has_many :all_bulbs, -> { unscope where: :name }, class_name: "Bulb" + has_many :all_bulbs, -> { unscope(where: :name) }, class_name: "Bulb" + has_many :all_bulbs2, -> { unscope(:where) }, class_name: "Bulb" + has_many :other_bulbs, -> { unscope(where: :name).where(name: "other") }, class_name: "Bulb" + has_many :old_bulbs, -> { rewhere(name: "old") }, class_name: "Bulb" has_many :funky_bulbs, class_name: "FunkyBulb", dependent: :destroy has_many :failed_bulbs, class_name: "FailedBulb", dependent: :destroy has_many :foo_bulbs, -> { where(name: "foo") }, class_name: "Bulb"