Skip to content
Permalink
Browse files

Don't allow destroyed object mutation after `save` or `save!` is called

Currently `object.save` will unfreeze the object, due to
`changes_applied` replaces frozen `@attributes` to new `@attributes`.

Since originally destroyed objects are not allowed to be mutated, `save`
and `save!` should not return success in that case.

Fixes #28563.
  • Loading branch information...
kamipo committed Jan 14, 2018
1 parent f1af27f commit 562dd0494a90d9d47849f052e8913f0050f3e494
@@ -1,3 +1,7 @@
* Don't allow destroyed object mutation after `save` or `save!` is called.

*Ryuta Kamizono*

* Take into account association conditions when deleting through records.

Fixes #18424.
@@ -694,6 +694,7 @@ def _relation_for_itself

def create_or_update(*args, &block)
_raise_readonly_record_error if readonly?
return false if destroyed?
result = new_record? ? _create_record(&block) : _update_record(*args, &block)
result != false
end
@@ -599,30 +599,52 @@ def test_update_all_with_non_standard_table_name
end

def test_delete_new_record
client = Client.new
client = Client.new(name: "37signals")
client.delete
assert client.frozen?

assert_not client.save
assert_raise(ActiveRecord::RecordNotSaved) { client.save! }

assert client.frozen?
assert_raise(RuntimeError) { client.name = "something else" }
end

def test_delete_record_with_associations
client = Client.find(3)
client.delete
assert client.frozen?
assert_kind_of Firm, client.firm

assert_not client.save
assert_raise(ActiveRecord::RecordNotSaved) { client.save! }

assert client.frozen?
assert_raise(RuntimeError) { client.name = "something else" }
end

def test_destroy_new_record
client = Client.new
client = Client.new(name: "37signals")
client.destroy
assert client.frozen?

assert_not client.save
assert_raise(ActiveRecord::RecordNotSaved) { client.save! }

assert client.frozen?
assert_raise(RuntimeError) { client.name = "something else" }
end

def test_destroy_record_with_associations
client = Client.find(3)
client.destroy
assert client.frozen?
assert_kind_of Firm, client.firm

assert_not client.save
assert_raise(ActiveRecord::RecordNotSaved) { client.save! }

assert client.frozen?
assert_raise(RuntimeError) { client.name = "something else" }
end

0 comments on commit 562dd04

Please sign in to comment.
You can’t perform that action at this time.