Dirty attributes aren't cleared if save fails. [#174 state:resolved]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
Xavier Noria 2008-05-13 00:46:57 +02:00 committed by Jeremy Kemper
parent a425cd1473
commit 593e21d6ae
3 changed files with 30 additions and 9 deletions

@ -69,19 +69,19 @@ def changes
changed.inject({}) { |h, attr| h[attr] = attribute_change(attr); h }
end
# Clear changed attributes after they are saved.
# Attempts to +save+ the record and clears changed attributes if successful.
def save_with_dirty(*args) #:nodoc:
save_without_dirty(*args)
ensure
changed_attributes.clear
if status = save_without_dirty(*args)
changed_attributes.clear
end
status
end
# Clear changed attributes after they are saved.
# Attempts to <tt>save!</tt> the record and clears changed attributes if successful.
def save_with_dirty!(*args) #:nodoc:
save_without_dirty!(*args)
ensure
status = save_without_dirty!(*args)
changed_attributes.clear
status
end
private

@ -78,7 +78,7 @@ def test_attribute_will_change!
end
def test_association_assignment_changes_foreign_key
pirate = Pirate.create!
pirate = Pirate.create!(:catchphrase => 'jarl')
pirate.parrot = Parrot.create!
assert pirate.changed?
assert_equal %w(parrot_id), pirate.changed
@ -115,6 +115,18 @@ def test_partial_update
end
end
def test_changed_attributes_should_be_preserved_if_save_failure
pirate = Pirate.new
pirate.parrot_id = 1
assert !pirate.save
check_pirate_after_save_failure(pirate)
pirate = Pirate.new
pirate.parrot_id = 1
assert_raises(ActiveRecord::RecordInvalid) { pirate.save! }
check_pirate_after_save_failure(pirate)
end
private
def with_partial_updates(klass, on = true)
old = klass.partial_updates?
@ -123,4 +135,11 @@ def with_partial_updates(klass, on = true)
ensure
klass.partial_updates = old
end
def check_pirate_after_save_failure(pirate)
assert pirate.changed?
assert pirate.parrot_id_changed?
assert_equal %w(parrot_id), pirate.changed
assert_nil pirate.parrot_id_was
end
end

@ -4,4 +4,6 @@ class Pirate < ActiveRecord::Base
has_many :treasures, :as => :looter
has_many :treasure_estimates, :through => :treasures, :source => :price_estimates
validates_presence_of :catchphrase
end