aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2019-08-01 15:38:03 -0700
committerGitHub <noreply@github.com>2019-08-01 15:38:03 -0700
commita0bb19fbfa590a3a773a24bc018b92fd5ba93b4d (patch)
tree2f8a1f3121b6b777d9e108190c035475ab1dd592
parent603cd18b0b9a06f0ed25013b3f8f34e524f87925 (diff)
downloadrails-a0bb19fbfa590a3a773a24bc018b92fd5ba93b4d.tar.gz
rails-a0bb19fbfa590a3a773a24bc018b92fd5ba93b4d.tar.bz2
rails-a0bb19fbfa590a3a773a24bc018b92fd5ba93b4d.zip
Add *_previously_was attribute methods when dirty tracking (#36836)
-rw-r--r--activemodel/CHANGELOG.md6
-rw-r--r--activemodel/lib/active_model/dirty.rb8
-rw-r--r--activerecord/test/cases/dirty_test.rb6
3 files changed, 19 insertions, 1 deletions
diff --git a/activemodel/CHANGELOG.md b/activemodel/CHANGELOG.md
index 9d77564c61..c301f4766d 100644
--- a/activemodel/CHANGELOG.md
+++ b/activemodel/CHANGELOG.md
@@ -1,3 +1,9 @@
+* Add *_previously_was attribute methods when dirty tracking. Example:
+ pirate.update(catchphrase: "Ahoy!")
+ pirate.previous_changes["catchphrase"] # => ["Thar She Blows!", "Ahoy!"]
+ pirate.catchphrase_previously_was # => "Thar She Blows!"
+
+ *DHH*
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activemodel/CHANGELOG.md) for previous changes.
diff --git a/activemodel/lib/active_model/dirty.rb b/activemodel/lib/active_model/dirty.rb
index aaefe00c83..245616502d 100644
--- a/activemodel/lib/active_model/dirty.rb
+++ b/activemodel/lib/active_model/dirty.rb
@@ -84,6 +84,7 @@ module ActiveModel
# person.previous_changes # => {"name" => [nil, "Bill"]}
# person.name_previously_changed? # => true
# person.name_previous_change # => [nil, "Bill"]
+ # person.name_previously_was # => nil
# person.reload!
# person.previous_changes # => {}
#
@@ -122,7 +123,7 @@ module ActiveModel
included do
attribute_method_suffix "_changed?", "_change", "_will_change!", "_was"
- attribute_method_suffix "_previously_changed?", "_previous_change"
+ attribute_method_suffix "_previously_changed?", "_previous_change", "_previously_was"
attribute_method_affix prefix: "restore_", suffix: "!"
end
@@ -180,6 +181,11 @@ module ActiveModel
mutations_before_last_save.changed?(attr_name.to_s)
end
+ # Dispatch target for <tt>*_previously_was</tt> attribute methods.
+ def attribute_previously_was(attr_name) # :nodoc:
+ mutations_before_last_save.original_value(attr_name.to_s)
+ end
+
# Restore all previous data of the provided attributes.
def restore_attributes(attr_names = changed)
attr_names.each { |attr_name| restore_attribute!(attr_name) }
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index a2a501a794..6aca7d93ad 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -491,6 +491,7 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal 4, pirate.previous_changes.size
assert_equal [nil, "arrr"], pirate.previous_changes["catchphrase"]
+ assert_equal nil, pirate.catchphrase_previously_was
assert_equal [nil, pirate.id], pirate.previous_changes["id"]
assert_nil pirate.previous_changes["updated_on"][0]
assert_not_nil pirate.previous_changes["updated_on"][1]
@@ -507,6 +508,7 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal 4, pirate.previous_changes.size
assert_equal [nil, "arrr"], pirate.previous_changes["catchphrase"]
+ assert_equal nil, pirate.catchphrase_previously_was
assert_equal [nil, pirate.id], pirate.previous_changes["id"]
assert_includes pirate.previous_changes, "updated_on"
assert_includes pirate.previous_changes, "created_on"
@@ -525,6 +527,7 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal 2, pirate.previous_changes.size
assert_equal ["arrr", "Me Maties!"], pirate.previous_changes["catchphrase"]
+ assert_equal "arrr", pirate.catchphrase_previously_was
assert_not_nil pirate.previous_changes["updated_on"][0]
assert_not_nil pirate.previous_changes["updated_on"][1]
assert_not pirate.previous_changes.key?("parrot_id")
@@ -539,6 +542,7 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal 2, pirate.previous_changes.size
assert_equal ["Me Maties!", "Thar She Blows!"], pirate.previous_changes["catchphrase"]
+ assert_equal "Me Maties!", pirate.catchphrase_previously_was
assert_not_nil pirate.previous_changes["updated_on"][0]
assert_not_nil pirate.previous_changes["updated_on"][1]
assert_not pirate.previous_changes.key?("parrot_id")
@@ -551,6 +555,7 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal 2, pirate.previous_changes.size
assert_equal ["Thar She Blows!", "Ahoy!"], pirate.previous_changes["catchphrase"]
+ assert_equal "Thar She Blows!", pirate.catchphrase_previously_was
assert_not_nil pirate.previous_changes["updated_on"][0]
assert_not_nil pirate.previous_changes["updated_on"][1]
assert_not pirate.previous_changes.key?("parrot_id")
@@ -563,6 +568,7 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal 2, pirate.previous_changes.size
assert_equal ["Ahoy!", "Ninjas suck!"], pirate.previous_changes["catchphrase"]
+ assert_equal "Ahoy!", pirate.catchphrase_previously_was
assert_not_nil pirate.previous_changes["updated_on"][0]
assert_not_nil pirate.previous_changes["updated_on"][1]
assert_not pirate.previous_changes.key?("parrot_id")