Active Model Dirty¶ ↑
提供了一种以与 Active Record 相同的方式跟踪对象中更改的方法。
实现 ActiveModel::Dirty 的要求是
-
在您的对象中
include ActiveModel::Dirty。 -
调用
define_attribute_methods并传入您要跟踪的每个方法。 -
在每次更改跟踪属性之前调用
*_will_change!。 -
在更改持久化后调用
changes_applied。 -
当您想重置更改信息时,调用
clear_changes_information。 -
当您想恢复先前数据时,调用
restore_attributes。
一个最小化的实现可以是
class Person include ActiveModel::Dirty define_attribute_methods :name def initialize @name = nil end def name @name end def name=(val) name_will_change! unless val == @name @name = val end def save # do persistence work changes_applied end def reload! # get the values from the persistence layer clear_changes_information end def rollback! restore_attributes end end
新实例化的 Person 对象未更改
person = Person.new person.changed? # => false
更改姓名
person.name = 'Bob' person.changed? # => true person.name_changed? # => true person.name_changed?(from: nil, to: "Bob") # => true person.name_was # => nil person.name_change # => [nil, "Bob"] person.name = 'Bill' person.name_change # => [nil, "Bill"]
保存更改
person.save person.changed? # => false person.name_changed? # => false
重置更改
person.previous_changes # => {"name" => [nil, "Bill"]} person.name_previously_changed? # => true person.name_previously_changed?(from: nil, to: "Bill") # => true person.name_previous_change # => [nil, "Bill"] person.name_previously_was # => nil person.reload! person.previous_changes # => {}
回滚更改
person.name = "Uncle Bob" person.rollback! person.name # => "Bill" person.name_changed? # => false
赋相同值不会更改属性
person.name = 'Bill' person.name_changed? # => false person.name_change # => nil
哪些属性已更改?
person.name = 'Bob' person.changed # => ["name"] person.changes # => {"name" => ["Bill", "Bob"]}
如果属性被就地修改,则使用 *_will_change! 来标记属性正在更改。否则,Active Model 无法跟踪就地属性的更改。请注意,Active Record 可以自动检测就地修改。您无需在 Active Record 模型上调用 *_will_change!。
person.name_will_change! person.name_change # => ["Bill", "Bill"] person.name << 'y' person.name_change # => ["Bill", "Billy"]
可以通过 name_changed? 调用方法,或者通过将参数传递给通用方法 attribute_changed?("name") 来调用。
- #
- A
- C
- P
- R
实例公共方法
*_change 链接
此方法是为每个属性生成的。
返回属性的旧值和新值。
person = Person.new person.name = 'Nick' person.name_change # => [nil, 'Nick']
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 155
*_changed? 链接
此方法是为每个属性生成的。
如果属性有未保存的更改,则返回 true。
person = Person.new person.name = 'Andrew' person.name_changed? # => true
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 144
*_previous_change 链接
此方法是为每个属性生成的。
返回最后一次保存之前属性的旧值和新值。
person = Person.new person.name = 'Emmanuel' person.save person.name_previous_change # => [nil, 'Emmanuel']
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 193
*_previously_changed?(**options) 链接
此方法是为每个属性生成的。
如果属性先前有未保存的更改,则返回 true。
person = Person.new person.name = 'Britanny' person.save person.name_previously_changed? # => true person.name_previously_changed?(from: nil, to: 'Britanny') # => true
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 129
*_previously_was 链接
此方法是为每个属性生成的。
返回最后一次保存之前属性的旧值。
person = Person.new person.name = 'Sage' person.save person.name_previously_was # => nil
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 205
*_was 链接
此方法是为每个属性生成的。
返回属性的旧值。
person = Person.new(name: 'Steph') person.name = 'Stephanie' person.name_was # => 'Steph'
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 182
*_will_change! 链接
此方法是为每个属性生成的。
如果属性被就地修改,则使用 *_will_change! 来标记属性正在更改。否则,Active Model 无法跟踪就地属性的更改。请注意,Active Record 可以自动检测就地修改。您无需在 Active Record 模型上调用 *_will_change!。
person = Person.new('Sandy') person.name_will_change! person.name_change # => ['Sandy', 'Sandy']
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 166
attribute_changed?(attr_name, **options) 链接
*_changed? 属性方法的调度目标。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 300 def attribute_changed?(attr_name, **options) mutations_from_database.changed?(attr_name.to_s, **options) end
attribute_previously_changed?(attr_name, **options) 链接
*_previously_changed? 属性方法的调度目标。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 310 def attribute_previously_changed?(attr_name, **options) mutations_before_last_save.changed?(attr_name.to_s, **options) end
attribute_previously_was(attr_name) 链接
*_previously_was 属性方法的调度目标。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 315 def attribute_previously_was(attr_name) mutations_before_last_save.original_value(attr_name.to_s) end
attribute_was(attr_name) 链接
*_was 属性方法的调度目标。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 305 def attribute_was(attr_name) mutations_from_database.original_value(attr_name.to_s) end
changed() 链接
返回一个包含具有未保存更改的属性名称的数组。
person.changed # => [] person.name = 'bob' person.changed # => ["name"]
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 295 def changed mutations_from_database.changed_attribute_names end
changed?() 链接
如果任何属性有未保存的更改,则返回 true,否则返回 false。
person.changed? # => false person.name = 'bob' person.changed? # => true
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 286 def changed? mutations_from_database.any_changes? end
changed_attributes() 链接
返回一个哈希,其中包含具有未保存更改的属性,并指示它们的原始值,例如 attr => 原始值。
person.name # => "bob" person.name = 'robert' person.changed_attributes # => {"name" => "bob"}
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 343 def changed_attributes mutations_from_database.changed_values end
changes() 链接
返回一个哈希,其中包含已更改的属性,并指示它们的原始值和新值,例如 attr => [原始值, 新值]。
person.changes # => {} person.name = 'bob' person.changes # => { "name" => ["bill", "bob"] }
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 353 def changes mutations_from_database.changes end
changes_applied() 链接
清除脏数据,并将 changes 移动到 previous_changes,将 mutations_from_database 移动到 mutations_before_last_save。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 272 def changes_applied unless defined?(@attributes) mutations_from_database.finalize_changes end @mutations_before_last_save = mutations_from_database forget_attribute_assignments @mutations_from_database = nil end
clear_*_change 链接
此方法是为每个属性生成的。
清除属性的所有脏数据:当前更改和先前更改。
person = Person.new(name: 'Chris') person.name = 'Jason' person.name_change # => ['Chris', 'Jason'] person.clear_name_change person.name_change # => nil
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 241 attribute_method_suffix "_previously_changed?", "_changed?", parameters: "**options"
clear_attribute_changes(attr_names) 链接
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 331 def clear_attribute_changes(attr_names) attr_names.each do |attr_name| clear_attribute_change(attr_name) end end
clear_changes_information() 链接
清除所有脏数据:当前更改和先前更改。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 325 def clear_changes_information @mutations_before_last_save = nil forget_attribute_assignments @mutations_from_database = nil end
previous_changes() 链接
返回一个哈希,其中包含模型保存前更改过的属性。
person.name # => "bob" person.name = 'robert' person.save person.previous_changes # => {"name" => ["bob", "robert"]}
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 363 def previous_changes mutations_before_last_save.changes end
restore_*! 链接
此方法是为每个属性生成的。
将属性恢复为旧值。
person = Person.new person.name = 'Amanda' person.restore_name! person.name # => nil
来源:在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 217
restore_attributes(attr_names = changed) 链接
恢复提供的属性的所有先前数据。
来源:显示 | 在 GitHub 上
# File activemodel/lib/active_model/dirty.rb, line 320 def restore_attributes(attr_names = changed) attr_names.each { |attr_name| restore_attribute!(attr_name) } end