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:
parent
a736e82170
commit
f614c5f108
2 changed files with 29 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue