Module: VirtualBox::AbstractModel::Dirty
- Included in:
- VirtualBox::AbstractModel, ExtraData
- Defined in:
- lib/virtualbox/abstract_model/dirty.rb
Overview
Tracks “dirtiness” of values for a class. Its not tied to AbstractModel in any way other than the namespace.
# Checking if a Value was Changed
Dynamic methods allow functionality for checking if values changed:
obj.foo_changed?
# Previous Value
Can also view the previous value of an attribute:
obj.foo # => "foo" initially
obj.foo = "bar"
obj.foo_was # => "foo"
# Previous and Current Value
Using the ‘_change` dynamic method, can view the changes of a field.
obj.foo # => "foo" initially
obj.foo = "bar"
obj.foo_change # => ["foo", "bar"]
# All Changes
Can also view all changes for a class with the ‘changes` method.
obj.foo # => "foo" initially
obj. # => "bar" initially
obj.foo = "far"
obj. = "baz"
obj.changes # => { :foo => ["foo", "far"], :bar => ["bar", "baz"]}
# Setting Dirty
Dirtiness tracking only occurs for values which the implementor explicitly sets as dirty. This is done with the #set_dirty! method. Example implementation below:
class Person
include VirtualBox::AbstractModel::Dirty
attr_reader :name
def name=(value)
set_dirty!(:name, @name, value)
@name = value
end
end
The above example has all the changes necessary to track changes on an attribute.
# Ignoring Dirtiness Tracking
Sometimes, for features such as mass assignment, dirtiness tracking should be disabled. This can be done with the ‘ignore_dirty` method.
ignore_dirty do |obj|
obj.name = "Foo"
end
obj.changed? # => false
# Clearing Dirty State
Sometimes, such as after saving a model, dirty states should be cleared. This can be done with the ‘clear_dirty!` method.
obj.clear_dirty!(:name)
obj.name_changed? # => false
If no specific field is speciied, ‘clear_dirty!` will clear the dirty status on the entire model.
obj.changed? # => assume true
obj.clear_dirty!
obj.changed? # => false
Instance Method Summary collapse
-
#changed?(attribute = nil) ⇒ Boolean
Returns boolean denoting if field changed or not.
-
#changes ⇒ Hash
Returns hash of changes.
-
#clear_dirty!(key = nil) ⇒ Object
Clears dirty state for a field.
-
#ignore_dirty {|_self| ... } ⇒ Object
Ignores any dirty changes during the duration of the block.
-
#method_missing(meth, *args) ⇒ Object
Method missing is used to implement the “magic” methods of ‘field_changed`, `field_change`, and `field_was`.
-
#set_dirty!(name, current, value) ⇒ Object
Manages dirty state for an attribute.
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(meth, *args) ⇒ Object
Method missing is used to implement the “magic” methods of ‘field_changed`, `field_change`, and `field_was`.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/virtualbox/abstract_model/dirty.rb', line 157 def method_missing(meth, *args) meth_string = meth.to_s if meth_string =~ /^(.+?)_changed\?$/ changed?($1.to_sym) elsif meth_string =~ /^(.+?)_change$/ changes[$1.to_sym] elsif meth_string =~ /^(.+?)_was$/ change = changes[$1.to_sym] if change.nil? nil else change[0] end else super end end |
Instance Method Details
#changed?(attribute = nil) ⇒ Boolean
Returns boolean denoting if field changed or not. If no attribute is specified, returns true of false showing whether the model changed at all.
139 140 141 142 143 144 145 |
# File 'lib/virtualbox/abstract_model/dirty.rb', line 139 def changed?(attribute = nil) if attribute.nil? !changes.empty? else changes.has_key?(attribute) end end |
#changes ⇒ Hash
Returns hash of changes. Keys are fields, values are an array of the original value and the current value.
151 152 153 |
# File 'lib/virtualbox/abstract_model/dirty.rb', line 151 def changes @changed_attributes ||= {} end |
#clear_dirty!(key = nil) ⇒ Object
Clears dirty state for a field.
116 117 118 119 120 121 122 |
# File 'lib/virtualbox/abstract_model/dirty.rb', line 116 def clear_dirty!(key=nil) if key.nil? @changed_attributes = {} else changes.delete(key) end end |
#ignore_dirty {|_self| ... } ⇒ Object
Ignores any dirty changes during the duration of the block. Guarantees the dirty state will be the same before and after the method call, but not within the block itself.
127 128 129 130 131 |
# File 'lib/virtualbox/abstract_model/dirty.rb', line 127 def ignore_dirty(&block) current_changes = changes.dup yield self @changed_attributes = current_changes end |
#set_dirty!(name, current, value) ⇒ Object
Manages dirty state for an attribute. This method will handle setting the dirty state of an attribute (or even clearing it if the old value is reset). Any implementors of this mixin should call this for any fields they want tracked.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/virtualbox/abstract_model/dirty.rb', line 94 def set_dirty!(name, current, value) if current != value name = name.to_sym # If its the first time this attribute has changed, store the # original value in the first field changes[name] ||= [current, nil] # Then store the changed value changes[name][1] = value # If the value changed back to the original value, remove from the # dirty hash if changes[name][0] == changes[name][1] changes.delete(name) end end end |