提交 bada18dc 编写于 作者: P Paul Gillard 提交者: Joshua Peek

Added reset_attribute! method to ActiveRecord::AttributeMethods::Dirty which...

Added reset_attribute! method to ActiveRecord::AttributeMethods::Dirty which will reset an attribute to its original value should it have changed.
Signed-off-by: NJoshua Peek <josh@joshpeek.com>
上级 c30a0ce3
...@@ -3,17 +3,17 @@ module AttributeMethods ...@@ -3,17 +3,17 @@ module AttributeMethods
# Track unsaved attribute changes. # Track unsaved attribute changes.
# #
# A newly instantiated object is unchanged: # A newly instantiated object is unchanged:
# person = Person.find_by_name('uncle bob') # person = Person.find_by_name('Uncle Bob')
# person.changed? # => false # person.changed? # => false
# #
# Change the name: # Change the name:
# person.name = 'Bob' # person.name = 'Bob'
# person.changed? # => true # person.changed? # => true
# person.name_changed? # => true # person.name_changed? # => true
# person.name_was # => 'uncle bob' # person.name_was # => 'Uncle Bob'
# person.name_change # => ['uncle bob', 'Bob'] # person.name_change # => ['Uncle Bob', 'Bob']
# person.name = 'Bill' # person.name = 'Bill'
# person.name_change # => ['uncle bob', 'Bill'] # person.name_change # => ['Uncle Bob', 'Bill']
# #
# Save the changes: # Save the changes:
# person.save # person.save
...@@ -26,21 +26,33 @@ module AttributeMethods ...@@ -26,21 +26,33 @@ module AttributeMethods
# person.name_change # => nil # person.name_change # => nil
# #
# Which attributes have changed? # Which attributes have changed?
# person.name = 'bob' # person.name = 'Bob'
# person.changed # => ['name'] # person.changed # => ['name']
# person.changes # => { 'name' => ['Bill', 'bob'] } # person.changes # => { 'name' => ['Bill', 'Bob'] }
#
# Resetting an attribute returns it to its original state:
# person.reset_name! # => 'Bill'
# person.changed? # => false
# person.name_changed? # => false
# person.name # => 'Bill'
# #
# Before modifying an attribute in-place: # Before modifying an attribute in-place:
# person.name_will_change! # person.name_will_change!
# person.name << 'by' # person.name << 'y'
# person.name_change # => ['uncle bob', 'uncle bobby'] # person.name_change # => ['Bill', 'Billy']
module Dirty module Dirty
extend ActiveSupport::Concern extend ActiveSupport::Concern
DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was'] DIRTY_AFFIXES = [
{ :suffix => '_changed?' },
{ :suffix => '_change' },
{ :suffix => '_will_change!' },
{ :suffix => '_was' },
{ :prefix => 'reset_', :suffix => '!' }
]
included do included do
attribute_method_suffix *DIRTY_SUFFIXES attribute_method_affix *DIRTY_AFFIXES
alias_method_chain :save, :dirty alias_method_chain :save, :dirty
alias_method_chain :save!, :dirty alias_method_chain :save!, :dirty
...@@ -118,6 +130,11 @@ def attribute_was(attr) ...@@ -118,6 +130,11 @@ def attribute_was(attr)
attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr) attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
end end
# Handle <tt>reset_*!</tt> for +method_missing+.
def reset_attribute!(attr)
self[attr] = changed_attributes[attr] if attribute_changed?(attr)
end
# Handle <tt>*_will_change!</tt> for +method_missing+. # Handle <tt>*_will_change!</tt> for +method_missing+.
def attribute_will_change!(attr) def attribute_will_change!(attr)
changed_attributes[attr] = clone_attribute_value(:read_attribute, attr) changed_attributes[attr] = clone_attribute_value(:read_attribute, attr)
...@@ -175,9 +192,9 @@ class << base ...@@ -175,9 +192,9 @@ class << base
def alias_attribute_with_dirty(new_name, old_name) def alias_attribute_with_dirty(new_name, old_name)
alias_attribute_without_dirty(new_name, old_name) alias_attribute_without_dirty(new_name, old_name)
DIRTY_SUFFIXES.each do |suffix| DIRTY_AFFIXES.each do |affixes|
module_eval <<-STR, __FILE__, __LINE__+1 module_eval <<-STR, __FILE__, __LINE__+1
def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end # def subject_changed?; self.title_changed?; end def #{affixes[:prefix]}#{new_name}#{affixes[:suffix]}; self.#{affixes[:prefix]}#{old_name}#{affixes[:suffix]}; end # def reset_subject!; self.reset_title!; end
STR STR
end end
end end
......
...@@ -62,6 +62,16 @@ def test_aliased_attribute_changes ...@@ -62,6 +62,16 @@ def test_aliased_attribute_changes
assert_equal parrot.name_change, parrot.title_change assert_equal parrot.name_change, parrot.title_change
end end
def test_reset_attribute!
pirate = Pirate.create!(:catchphrase => 'Yar!')
pirate.catchphrase = 'Ahoy!'
pirate.reset_catchphrase!
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 def test_nullable_number_not_marked_as_changed_if_new_value_is_blank
pirate = Pirate.new pirate = Pirate.new
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册