1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix deleting through records when using has_many through with source_type

Currently deleting through records doesn't respect `source_type`. It
should not be ignored in that case.

Related #23209.
Fixes #24116.
This commit is contained in:
Ryuta Kamizono 2018-01-08 00:49:11 +09:00
parent a736e82170
commit f614c5f108
2 changed files with 29 additions and 20 deletions

View file

@ -38,24 +38,22 @@ module ActiveRecord
def construct_join_attributes(*records)
ensure_mutable
if source_reflection.association_primary_key(reflection.klass) == reflection.klass.primary_key
association_primary_key = source_reflection.association_primary_key(reflection.klass)
if association_primary_key == reflection.klass.primary_key && !options[:source_type]
join_attributes = { source_reflection.name => records }
else
join_attributes = {
source_reflection.foreign_key =>
records.map { |record|
record.send(source_reflection.association_primary_key(reflection.klass))
}
source_reflection.foreign_key => records.map(&association_primary_key.to_sym)
}
end
if options[:source_type]
join_attributes[source_reflection.foreign_type] =
records.map { |record| record.class.base_class.name }
join_attributes[source_reflection.foreign_type] = [ options[:source_type] ]
end
if records.count == 1
Hash[join_attributes.map { |k, v| [k, v.first] }]
join_attributes.transform_values!(&:first)
else
join_attributes
end

View file

@ -254,23 +254,34 @@ class ReflectionTest < ActiveRecord::TestCase
end
def test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case
@hotel = Hotel.create!
@department = @hotel.departments.create!
@department.chefs.create!(employable: CakeDesigner.create!)
@department.chefs.create!(employable: DrinkDesigner.create!)
hotel = Hotel.create!
department = hotel.departments.create!
department.chefs.create!(employable: CakeDesigner.create!)
department.chefs.create!(employable: DrinkDesigner.create!)
assert_equal 1, @hotel.cake_designers.size
assert_equal 1, @hotel.drink_designers.size
assert_equal 2, @hotel.chefs.size
assert_equal 1, hotel.cake_designers.size
assert_equal 1, hotel.cake_designers.count
assert_equal 1, hotel.drink_designers.size
assert_equal 1, hotel.drink_designers.count
assert_equal 2, hotel.chefs.size
assert_equal 2, hotel.chefs.count
end
def test_scope_chain_does_not_interfere_with_hmt_with_polymorphic_case_and_sti
@hotel = Hotel.create!
@hotel.mocktail_designers << MocktailDesigner.create!
hotel = Hotel.create!
hotel.mocktail_designers << MocktailDesigner.create!
assert_equal 1, @hotel.mocktail_designers.size
assert_equal 1, @hotel.mocktail_designers.count
assert_equal 1, @hotel.chef_lists.size
assert_equal 1, hotel.mocktail_designers.size
assert_equal 1, hotel.mocktail_designers.count
assert_equal 1, hotel.chef_lists.size
assert_equal 1, hotel.chef_lists.count
hotel.mocktail_designers = []
assert_equal 0, hotel.mocktail_designers.size
assert_equal 0, hotel.mocktail_designers.count
assert_equal 0, hotel.chef_lists.size
assert_equal 0, hotel.chef_lists.count
end
def test_scope_chain_of_polymorphic_association_does_not_leak_into_other_hmt_associations