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.
|
* 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.
|
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
|
def decrement_counters_before_last_save
|
||||||
if reflection.polymorphic?
|
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
|
else
|
||||||
model_was = klass
|
model_was = klass
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,7 +49,7 @@ module ActiveRecord::Associations::Builder # :nodoc:
|
||||||
if reflection.polymorphic?
|
if reflection.polymorphic?
|
||||||
foreign_type = reflection.foreign_type
|
foreign_type = reflection.foreign_type
|
||||||
klass = changes[foreign_type] && changes[foreign_type].first || o.public_send(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
|
else
|
||||||
klass = association.klass
|
klass = association.klass
|
||||||
end
|
end
|
||||||
|
|
|
@ -1331,6 +1331,47 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
|
||||||
assert_equal groucho, sponsor.thing
|
assert_equal groucho, sponsor.thing
|
||||||
end
|
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
|
def test_build_with_conditions
|
||||||
client = companies(:second_client)
|
client = companies(:second_client)
|
||||||
firm = client.build_bob_firm
|
firm = client.build_bob_firm
|
||||||
|
|
Loading…
Reference in a new issue