From bdaeee19f959f46064f678807be72f1f4e5d7761 Mon Sep 17 00:00:00 2001 From: Sampson Crowley Date: Sun, 20 Sep 2020 10:24:19 -0600 Subject: [PATCH] move ActiveRecord::Persistance#becomes logic into initialize block --- activerecord/lib/active_record/persistence.rb | 15 +++++++++------ activerecord/test/cases/inheritance_test.rb | 10 ++++++++++ activerecord/test/models/vegetables.rb | 8 ++++++++ 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index b2bdd2af04..1fbed559c8 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -569,12 +569,15 @@ def destroy! # If you want to change the sti column as well, use #becomes! instead. def becomes(klass) became = klass.allocate - became.send(:initialize) - became.instance_variable_set(:@attributes, @attributes) - became.instance_variable_set(:@mutations_from_database, @mutations_from_database ||= nil) - became.instance_variable_set(:@new_record, new_record?) - became.instance_variable_set(:@destroyed, destroyed?) - became.errors.copy!(errors) + + became.send(:initialize) do |becoming| + becoming.instance_variable_set(:@attributes, @attributes) + becoming.instance_variable_set(:@mutations_from_database, @mutations_from_database ||= nil) + becoming.instance_variable_set(:@new_record, new_record?) + becoming.instance_variable_set(:@destroyed, destroyed?) + becoming.errors.copy!(errors) + end + became end diff --git a/activerecord/test/cases/inheritance_test.rb b/activerecord/test/cases/inheritance_test.rb index 80b83690ca..b316e6a637 100644 --- a/activerecord/test/cases/inheritance_test.rb +++ b/activerecord/test/cases/inheritance_test.rb @@ -227,6 +227,16 @@ def test_alt_becomes_works_with_sti assert_kind_of Cabbage, cabbage end + def test_becomes_sets_variables_before_initialization_callbacks + vegetable = Vegetable.create!(name: "yelling carrot") + assert_kind_of Vegetable, vegetable + assert_equal "yelling carrot", vegetable.name + + yelling_veggie = vegetable.becomes(YellingVegetable) + assert_equal "YELLING CARROT", yelling_veggie.name, "YellingVegetable name should be YELLING CARROT" + assert_equal "YELLING CARROT", vegetable.name, "Vegetable name should be YELLING CARROT after becoming a YellingVegetable" + end + def test_becomes_and_change_tracking_for_inheritance_columns cucumber = Vegetable.find(1) cabbage = cucumber.becomes!(Cabbage) diff --git a/activerecord/test/models/vegetables.rb b/activerecord/test/models/vegetables.rb index cfaab08ed1..0cb3ba386e 100644 --- a/activerecord/test/models/vegetables.rb +++ b/activerecord/test/models/vegetables.rb @@ -23,3 +23,11 @@ class KingCole < GreenCabbage class RedCabbage < Cabbage belongs_to :seller, class_name: "Company" end + +class YellingVegetable < Vegetable + after_initialize :format_name + + def format_name + self.name = name&.upcase + end +end