mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Add ActiveModel::Dirty#[attr_name]_previously_changed?
and
`ActiveModel::Dirty#[attr_name]_previous_change` to improve access to recorded changes after the model has been saved. It makes the dirty-attributes query methods consistent before and after saving.
This commit is contained in:
parent
b12abe6733
commit
f072db8e4f
3 changed files with 43 additions and 2 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
* Add `ActiveModel::Dirty#[attr_name]_previously_changed?` and
|
||||||
|
`ActiveModel::Dirty#[attr_name]_previous_change` to improve access
|
||||||
|
to recorded changes after the model has been saved.
|
||||||
|
|
||||||
|
It makes the dirty-attributes query methods consistent before and after
|
||||||
|
saving.
|
||||||
|
|
||||||
|
*Fernando Tapia Rico*
|
||||||
|
|
||||||
* Deprecate the `:tokenizer` option for `validates_length_of`, in favor of
|
* Deprecate the `:tokenizer` option for `validates_length_of`, in favor of
|
||||||
plain Ruby.
|
plain Ruby.
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,11 @@ module ActiveModel
|
||||||
#
|
#
|
||||||
# Reset the changes:
|
# Reset the changes:
|
||||||
#
|
#
|
||||||
# person.previous_changes # => {"name" => ["Uncle Bob", "Bill"]}
|
# person.previous_changes # => {"name" => ["Uncle Bob", "Bill"]}
|
||||||
|
# person.name_previously_changed? # => true
|
||||||
|
# person.name_previous_change # => ["Uncle Bob", "Bill"]
|
||||||
# person.reload!
|
# person.reload!
|
||||||
# person.previous_changes # => {}
|
# person.previous_changes # => {}
|
||||||
#
|
#
|
||||||
# Rollback the changes:
|
# Rollback the changes:
|
||||||
#
|
#
|
||||||
|
@ -115,6 +117,7 @@ module ActiveModel
|
||||||
|
|
||||||
included do
|
included do
|
||||||
attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
|
attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
|
||||||
|
attribute_method_suffix '_previously_changed?', '_previous_change'
|
||||||
attribute_method_affix prefix: 'restore_', suffix: '!'
|
attribute_method_affix prefix: 'restore_', suffix: '!'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -179,6 +182,11 @@ module ActiveModel
|
||||||
attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
|
attribute_changed?(attr) ? changed_attributes[attr] : __send__(attr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Handles <tt>*_previously_changed?</tt> for +method_missing+.
|
||||||
|
def attribute_previously_changed?(attr, options = {}) #:nodoc:
|
||||||
|
previous_changes_include?(attr)
|
||||||
|
end
|
||||||
|
|
||||||
# Restore all previous data of the provided attributes.
|
# Restore all previous data of the provided attributes.
|
||||||
def restore_attributes(attributes = changed)
|
def restore_attributes(attributes = changed)
|
||||||
attributes.each { |attr| restore_attribute! attr }
|
attributes.each { |attr| restore_attribute! attr }
|
||||||
|
@ -192,6 +200,12 @@ module ActiveModel
|
||||||
end
|
end
|
||||||
alias attribute_changed_by_setter? changes_include?
|
alias attribute_changed_by_setter? changes_include?
|
||||||
|
|
||||||
|
# Returns +true+ if attr_name were changed before the model was saved,
|
||||||
|
# +false+ otherwise.
|
||||||
|
def previous_changes_include?(attr_name)
|
||||||
|
@previously_changed.include?(attr_name)
|
||||||
|
end
|
||||||
|
|
||||||
# Removes current changes and makes them accessible through +previous_changes+.
|
# Removes current changes and makes them accessible through +previous_changes+.
|
||||||
def changes_applied # :doc:
|
def changes_applied # :doc:
|
||||||
@previously_changed = changes
|
@previously_changed = changes
|
||||||
|
@ -209,6 +223,11 @@ module ActiveModel
|
||||||
[changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
|
[changed_attributes[attr], __send__(attr)] if attribute_changed?(attr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Handles <tt>*_previous_change</tt> for +method_missing+.
|
||||||
|
def attribute_previous_change(attr)
|
||||||
|
@previously_changed[attr] if attribute_previously_changed?(attr)
|
||||||
|
end
|
||||||
|
|
||||||
# Handles <tt>*_will_change!</tt> for +method_missing+.
|
# Handles <tt>*_will_change!</tt> for +method_missing+.
|
||||||
def attribute_will_change!(attr)
|
def attribute_will_change!(attr)
|
||||||
return if attribute_changed?(attr)
|
return if attribute_changed?(attr)
|
||||||
|
|
|
@ -137,6 +137,19 @@ class DirtyTest < ActiveModel::TestCase
|
||||||
assert_equal [nil, "Jericho Cane"], @model.previous_changes['name']
|
assert_equal [nil, "Jericho Cane"], @model.previous_changes['name']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "setting new attributes should not affect previous changes" do
|
||||||
|
@model.name = "Jericho Cane"
|
||||||
|
@model.save
|
||||||
|
@model.name = "DudeFella ManGuy"
|
||||||
|
assert_equal [nil, "Jericho Cane"], @model.name_previous_change
|
||||||
|
end
|
||||||
|
|
||||||
|
test "saving should preserve model's previous changed status" do
|
||||||
|
@model.name = "Jericho Cane"
|
||||||
|
@model.save
|
||||||
|
assert @model.name_previously_changed?
|
||||||
|
end
|
||||||
|
|
||||||
test "previous value is preserved when changed after save" do
|
test "previous value is preserved when changed after save" do
|
||||||
assert_equal({}, @model.changed_attributes)
|
assert_equal({}, @model.changed_attributes)
|
||||||
@model.name = "Paul"
|
@model.name = "Paul"
|
||||||
|
|
Loading…
Reference in a new issue