From fec5bb1ada0313bc0f9ef4211fdfa370f9c90353 Mon Sep 17 00:00:00 2001 From: Paul Gillard Date: Sat, 4 Jul 2009 11:50:16 +0100 Subject: [PATCH] Add method to reset attributes on dirty records Added attribute_reset method which will reset an attribute to its original value should it have changed. --- activerecord/lib/active_record/dirty.rb | 29 ++++++++++++++++++++--------- activerecord/test/cases/dirty_test.rb | 10 ++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb index 178767e..b0f6692 100644 --- a/activerecord/lib/active_record/dirty.rb +++ b/activerecord/lib/active_record/dirty.rb @@ -2,17 +2,17 @@ module ActiveRecord # Track unsaved attribute changes. # # A newly instantiated object is unchanged: - # person = Person.find_by_name('uncle bob') + # person = Person.find_by_name('Uncle Bob') # person.changed? # => false # # Change the name: # person.name = 'Bob' # person.changed? # => true # person.name_changed? # => true - # person.name_was # => 'uncle bob' - # person.name_change # => ['uncle bob', 'Bob'] + # person.name_was # => 'Uncle Bob' + # person.name_change # => ['Uncle Bob', 'Bob'] # person.name = 'Bill' - # person.name_change # => ['uncle bob', 'Bill'] + # person.name_change # => ['Uncle Bob', 'Bill'] # # Save the changes: # person.save @@ -25,18 +25,24 @@ module ActiveRecord # person.name_change # => nil # # Which attributes have changed? - # person.name = 'bob' + # person.name = 'Bob' # person.changed # => ['name'] - # person.changes # => { 'name' => ['Bill', 'bob'] } + # person.changes # => { 'name' => ['Bill', 'Bob'] } + # + # Resetting an attribute returns it to its original state: + # person.name_reset # => 'Bill' + # person.changed? # => false + # person.name_changed? # => false + # person.name # => 'Bill' # # Before modifying an attribute in-place: # person.name_will_change! - # person.name << 'by' - # person.name_change # => ['uncle bob', 'uncle bobby'] + # person.name << 'y' + # person.name_change # => ['Bill', 'Billy'] module Dirty extend ActiveSupport::Concern - DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was'] + DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was', '_reset'] included do attribute_method_suffix *DIRTY_SUFFIXES @@ -117,6 +123,11 @@ module ActiveRecord def attribute_was(attr) attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) end + + # Handle *_reset for +method_missing+. + def attribute_reset(attr) + attribute_changed?(attr) ? self[attr] = changed_attributes[attr] : __send__(attr) + end # Handle *_will_change! for +method_missing+. def attribute_will_change!(attr) diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index ac95bac..bc0eb80 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -62,6 +62,16 @@ class DirtyTest < ActiveRecord::TestCase assert_equal parrot.name_change, parrot.title_change end + def test_attribute_reset + pirate = Pirate.create!(:catchphrase => 'Yar!') + pirate.catchphrase = 'Ahoy!' + + pirate.catchphrase_reset + assert_equal "Yar!", pirate.catchphrase + assert_equal Hash.new, pirate.changes + assert !pirate.catchphrase_changed? + end + def test_nullable_number_not_marked_as_changed_if_new_value_is_blank pirate = Pirate.new -- 1.6.0.5