diff options
author | James Coleman <jtc331@gmail.com> | 2012-03-02 15:37:48 -0500 |
---|---|---|
committer | James Coleman <jtc331@gmail.com> | 2012-03-02 16:31:18 -0500 |
commit | 217a8b01b1349d50fc9c331e9411034289c640ab (patch) | |
tree | cfe228d5ee1970a31f47263b07a02a041a47cfdf /activerecord | |
parent | 5497432d71b88ae4b99c6c59199eba95d81f28f6 (diff) | |
download | rails-217a8b01b1349d50fc9c331e9411034289c640ab.tar.gz rails-217a8b01b1349d50fc9c331e9411034289c640ab.tar.bz2 rails-217a8b01b1349d50fc9c331e9411034289c640ab.zip |
Unset association when existing record is destroyed.
To avoid foreign key errors (and invalid data) in the database, when a belongs_to association is destroyed, it should also be nil'd out on the parent object.
Diffstat (limited to 'activerecord')
-rw-r--r-- | activerecord/lib/active_record/autosave_association.rb | 1 | ||||
-rw-r--r-- | activerecord/test/cases/nested_attributes_test.rb | 16 |
2 files changed, 17 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index d468663084..0468a73c7d 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -402,6 +402,7 @@ module ActiveRecord autosave = reflection.options[:autosave] if autosave && record.marked_for_destruction? + self[reflection.foreign_key] = nil record.destroy elsif autosave != false saved = record.save(:validate => !autosave) if record.new_record? || (autosave && record.changed_for_autosave?) diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index 2ae9cb4888..131f2de158 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -450,6 +450,22 @@ class TestNestedAttributesOnABelongsToAssociation < ActiveRecord::TestCase end end + def test_should_unset_association_when_an_existing_record_is_destroyed + @ship.reload + original_pirate_id = @ship.pirate.id + @ship.attributes = {:pirate_attributes => {:id => @ship.pirate.id, :_destroy => true}} + @ship.save! + + assert_empty Pirate.where(["id = ?", original_pirate_id]) + assert_nil @ship.pirate_id + assert_nil @ship.pirate + + @ship.reload + assert_empty Pirate.where(["id = ?", original_pirate_id]) + assert_nil @ship.pirate_id + assert_nil @ship.pirate + end + def test_should_not_destroy_an_existing_record_if_destroy_is_not_truthy [nil, '0', 0, 'false', false].each do |not_truth| @ship.update_attributes(:pirate_attributes => { :id => @ship.pirate.id, :_destroy => not_truth }) |