aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/store.rb
diff options
context:
space:
mode:
authorpalkan <dementiev.vm@gmail.com>2015-03-14 19:50:02 +0300
committerVladimir Dementyev <dementiev.vm@gmail.com>2019-03-25 18:49:44 -0400
commit61a39ffcc6614d4369f524b5687309d9f12f279f (patch)
tree9a989e8712d56452ba19705153edb9043a885e9c /activerecord/lib/active_record/store.rb
parent6b5130720eee785b45dfc0fc5044224cdc2b6c98 (diff)
downloadrails-61a39ffcc6614d4369f524b5687309d9f12f279f.tar.gz
rails-61a39ffcc6614d4369f524b5687309d9f12f279f.tar.bz2
rails-61a39ffcc6614d4369f524b5687309d9f12f279f.zip
Add dirty methods for store accessors
Diffstat (limited to 'activerecord/lib/active_record/store.rb')
-rw-r--r--activerecord/lib/active_record/store.rb28
1 files changed, 28 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb
index 3537e2d008..03225668da 100644
--- a/activerecord/lib/active_record/store.rb
+++ b/activerecord/lib/active_record/store.rb
@@ -11,6 +11,10 @@ module ActiveRecord
# of the model. This is very helpful for easily exposing store keys to a form or elsewhere that's
# already built around just accessing attributes on the model.
#
+ # Every accessor comes with dirty tracking methods (+key_changed?+, +key_was+ and +key_change+).
+ #
+ # NOTE: There is no +key_will_change!+ method for accessors, use +store_will_change!+ instead.
+ #
# Make sure that you declare the database column used for the serialized store as a text, so there's
# plenty of room.
#
@@ -49,6 +53,12 @@ module ActiveRecord
# u.settings[:country] # => 'Denmark'
# u.settings['country'] # => 'Denmark'
#
+ # # Dirty tracking
+ # u.color = 'green'
+ # u.color_changed? # => true
+ # u.color_was # => 'black'
+ # u.color_change # => ['black', 'red']
+ #
# # Add additional accessors to an existing store through store_accessor
# class SuperUser < User
# store_accessor :settings, :privileges, :servants
@@ -127,6 +137,24 @@ module ActiveRecord
define_method(accessor_key) do
read_store_attribute(store_attribute, key)
end
+
+ define_method("#{accessor_key}_changed?") do
+ return false unless attribute_changed?(store_attribute)
+ prev_store, new_store = changes[store_attribute]
+ prev_store&.dig(key) != new_store&.dig(key)
+ end
+
+ define_method("#{accessor_key}_change") do
+ return unless attribute_changed?(store_attribute)
+ prev_store, new_store = changes[store_attribute]
+ [prev_store&.dig(key), new_store&.dig(key)]
+ end
+
+ define_method("#{accessor_key}_was") do
+ return unless attribute_changed?(store_attribute)
+ prev_store, _new_store = changes[store_attribute]
+ prev_store&.dig(key)
+ end
end
end