Merge pull request #3023 from Tho85/preserve_sti_type

AR::Base.becomes should not change the STI type

Conflicts:
	activerecord/CHANGELOG.md
This commit is contained in:
Rafael Mendonça França 2012-11-18 23:25:13 -02:00
commit 0cc9c1255d
3 changed files with 31 additions and 2 deletions

@ -1,5 +1,12 @@
## Rails 4.0.0 (unreleased) ##
* Don't change STI type when calling `ActiveRecord::Base#becomes`.
Add `ActiveRecord::Base#becomes!` with the previous behavior.
See #3023 for more information.
*Thomas Hollstegge*
* `rename_index` can be used inside a `change_table` block.
change_table :accounts do |t|

@ -155,7 +155,18 @@ def becomes(klass)
became.instance_variable_set("@new_record", new_record?)
became.instance_variable_set("@destroyed", destroyed?)
became.instance_variable_set("@errors", errors)
became.public_send("#{klass.inheritance_column}=", klass.name) unless self.class.descends_from_active_record?
became
end
# Wrapper around +becomes+ that also changes the instance's sti column value.
# This is especially useful if you want to persist the changed class in your
# database.
#
# Note: The old instance's sti column value will be changed too, as both objects
# share the same set of attributes.
def becomes!(klass)
became = becomes(klass)
became.public_send("#{klass.inheritance_column}=", klass.sti_name) unless self.class.descends_from_active_record?
became
end

@ -280,12 +280,23 @@ def test_update_for_record_with_only_primary_key
def test_update_sti_type
assert_instance_of Reply, topics(:second)
topic = topics(:second).becomes(Topic)
topic = topics(:second).becomes!(Topic)
assert_instance_of Topic, topic
topic.save!
assert_instance_of Topic, Topic.find(topic.id)
end
def test_preserve_original_sti_type
reply = topics(:second)
assert_equal "Reply", reply.type
topic = reply.becomes(Topic)
assert_equal "Reply", reply.type
assert_instance_of Topic, topic
assert_equal "Reply", topic.type
end
def test_delete
topic = Topic.find(1)
assert_equal topic, topic.delete, 'topic.delete did not return self'