aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonel Galan <leonelgalan@gmail.com>2017-09-06 13:31:23 -0400
committerLeonel Galan <leonelgalan@gmail.com>2018-01-22 10:04:47 -0500
commit3562331669443b600f1cf9fd93a0cddaaf94d319 (patch)
treebd19f9c4b9452e4961bbcbe16002cb370d9c76ca
parent7bb0b397ea51b0e41b5ebdf4fe5edcfc7345b600 (diff)
downloadrails-3562331669443b600f1cf9fd93a0cddaaf94d319.tar.gz
rails-3562331669443b600f1cf9fd93a0cddaaf94d319.tar.bz2
rails-3562331669443b600f1cf9fd93a0cddaaf94d319.zip
Ignores a default subclass when `becomes(Parent)`
Fixes issue described in #30399: A default value on the inheritance column prevented `child.becomes(Parent)` to return an instance of `Parent` as expected, instead it returns an instance of the default subclass. The change was introduced by #17169 and it was meant to affect initialization, alone. Where `Parent.new` is expected to return an instance of the default subclass.
-rw-r--r--activerecord/lib/active_record/persistence.rb3
-rw-r--r--activerecord/test/cases/persistence_test.rb16
2 files changed, 18 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index cdd54cc502..a45d011d75 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -359,7 +359,8 @@ module ActiveRecord
# Any change to the attributes on either instance will affect both instances.
# If you want to change the sti column as well, use #becomes! instead.
def becomes(klass)
- became = klass.new
+ became = klass.allocate
+ became.send(:initialize)
became.instance_variable_set("@attributes", @attributes)
became.instance_variable_set("@mutations_from_database", @mutations_from_database) if defined?(@mutations_from_database)
became.instance_variable_set("@new_record", new_record?)
diff --git a/activerecord/test/cases/persistence_test.rb b/activerecord/test/cases/persistence_test.rb
index 0edca96cf5..d242fff442 100644
--- a/activerecord/test/cases/persistence_test.rb
+++ b/activerecord/test/cases/persistence_test.rb
@@ -473,6 +473,22 @@ class PersistenceTest < ActiveRecord::TestCase
assert_instance_of Reply, Reply.find(reply.id)
end
+ def test_becomes_default_sti_subclass
+ original_type = Topic.columns_hash["type"].default
+ ActiveRecord::Base.connection.change_column_default :topics, :type, "Reply"
+ Topic.reset_column_information
+
+ reply = topics(:second)
+ assert_instance_of Reply, reply
+
+ topic = reply.becomes(Topic)
+ assert_instance_of Topic, topic
+
+ ensure
+ ActiveRecord::Base.connection.change_column_default :topics, :type, original_type
+ Topic.reset_column_information
+ end
+
def test_update_after_create
klass = Class.new(Topic) do
def self.name; "Topic"; end