mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Use polymorphic_class_for
over constantize
This commit fixes 2 cases where `constantize` was used instead of of calling `polymorphic_class_for` to retrieve the class associated with a given string for polymorphic `belongs_to`.
This commit is contained in:
parent
e1f90a30a2
commit
2ea5ff9e13
4 changed files with 53 additions and 2 deletions
|
@ -1,3 +1,12 @@
|
|||
* Fix 2 cases that inferred polymorphic class from the association's `foreign_type`
|
||||
using `String#constantize` instead of the model's `polymorphic_class_for`.
|
||||
|
||||
When updating a polymorphic association, the old `foreign_type` was not inferred correctly when:
|
||||
1. `touch`ing the previously associated record
|
||||
2. updating the previously associated record's `counter_cache`
|
||||
|
||||
*Jimmy Bourassa*
|
||||
|
||||
* Add config option for ignoring tables when dumping the schema cache.
|
||||
|
||||
Applications can now be configured to ignore certain tables when dumping the schema cache.
|
||||
|
|
|
@ -55,7 +55,8 @@ module ActiveRecord
|
|||
|
||||
def decrement_counters_before_last_save
|
||||
if reflection.polymorphic?
|
||||
model_was = owner.attribute_before_last_save(reflection.foreign_type)&.constantize
|
||||
model_type_was = owner.attribute_before_last_save(reflection.foreign_type)
|
||||
model_was = owner.class.polymorphic_class_for(model_type_was) if model_type_was
|
||||
else
|
||||
model_was = klass
|
||||
end
|
||||
|
|
|
@ -49,7 +49,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
|||
if reflection.polymorphic?
|
||||
foreign_type = reflection.foreign_type
|
||||
klass = changes[foreign_type] && changes[foreign_type].first || o.public_send(foreign_type)
|
||||
klass = klass.constantize
|
||||
klass = o.class.polymorphic_class_for(klass)
|
||||
else
|
||||
klass = association.klass
|
||||
end
|
||||
|
|
|
@ -1331,6 +1331,47 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
|||
assert_equal groucho, sponsor.thing
|
||||
end
|
||||
|
||||
class WheelPolymorphicName < ActiveRecord::Base
|
||||
self.table_name = "wheels"
|
||||
belongs_to :wheelable, polymorphic: true, counter_cache: :wheels_count, touch: :wheels_owned_at
|
||||
|
||||
def self.polymorphic_class_for(name)
|
||||
raise "Unexpected name: #{name}" unless name == "polymorphic_car"
|
||||
CarPolymorphicName
|
||||
end
|
||||
end
|
||||
|
||||
class CarPolymorphicName < ActiveRecord::Base
|
||||
self.table_name = "cars"
|
||||
has_many :wheels, as: :wheelable
|
||||
|
||||
def self.polymorphic_name
|
||||
"polymorphic_car"
|
||||
end
|
||||
end
|
||||
|
||||
def test_polymorphic_with_custom_name_counter_cache
|
||||
car = CarPolymorphicName.create!
|
||||
wheel = WheelPolymorphicName.create!(wheelable_type: "polymorphic_car", wheelable_id: car.id)
|
||||
assert_equal 1, car.reload.wheels_count
|
||||
|
||||
wheel.update! wheelable: nil
|
||||
|
||||
assert_equal 0, car.reload.wheels_count
|
||||
end
|
||||
|
||||
def test_polymorphic_with_custom_name_touch_old_belongs_to_model
|
||||
car = CarPolymorphicName.create!
|
||||
wheel = WheelPolymorphicName.create!(wheelable: car)
|
||||
|
||||
touch_time = 1.day.ago.round
|
||||
travel_to(touch_time) do
|
||||
wheel.update!(wheelable: nil)
|
||||
end
|
||||
|
||||
assert_equal touch_time, car.reload.wheels_owned_at
|
||||
end
|
||||
|
||||
def test_build_with_conditions
|
||||
client = companies(:second_client)
|
||||
firm = client.build_bob_firm
|
||||
|
|
Loading…
Reference in a new issue