Class: AttributeKit::AttributeHash
- Inherits:
-
Hash
- Object
- Hash
- AttributeKit::AttributeHash
- Defined in:
- lib/attribute-kit/attribute_hash.rb
Overview
AttributeHash inherits from and extends Hash, to provide tracking of attribute status (changed/deleted keys).
Instance Method Summary collapse
-
#[]=(k, v) ⇒ Object
(also: #store)
Assigns a value to a key.
-
#clean_attributes(&block) {|dirty_attrs| ... } ⇒ Object
Calls a block with a hash of all keys, actions (:changed or :deleted), and current values (if :changed) of keys that have changed since the object was last marked clean.
-
#clear ⇒ AttributeHash
Clear all contents of the object and mark it as dirty.
-
#delete(k) ⇒ Object
Delete a key-value pair.
-
#delete_if {|key, value| ... } ⇒ AttributeHash
Delete keys matching an expression in the provided block.
-
#deleted_keys ⇒ Array
Returns the set of keys that have been deleted since the AttributeHash was last marked clean.
-
#dirty? ⇒ Boolean
Check whether the contents of the object have changed since the last time clean_attributes was run.
-
#dirty_keys ⇒ Array
Returns the set of keys that have been modified since the AttributeHash was last marked clean.
-
#initialize(*args) ⇒ AttributeHash
constructor
Creates a new instance, using identical syntax to Hash.
-
#keep_if {|key, value| ... } ⇒ AttributeHash
Delete keys not matching an expression in the provided block.
-
#merge!(other_hash) {|key, oldval, newval| ... } ⇒ AttributeHash
(also: #update)
Combine the contents of this object with the contents of the supplied hash, calling an optional supplied block to determine what value is used when there are duplicate keys.
- #method_missing(method, *args, &block) ⇒ Object
-
#reject! {|key, value| ... } ⇒ AttributeHash, Nil
Delete keys matching an expression in the provided block.
-
#replace(other_hash) ⇒ AttributeHash
Replace the contents of this object with the contents of the supplied hash.
-
#select! {|key, value| ... } ⇒ AttributeHash, Nil
Delete keys not matching an expression in the provided block.
-
#shift ⇒ Array
Returns a key-value pair from the instance and deletes it.
Constructor Details
#initialize(*args) ⇒ AttributeHash
Creates a new instance, using identical syntax to Hash
70 71 72 73 74 |
# File 'lib/attribute-kit/attribute_hash.rb', line 70 def initialize(*args) super(*args) @dirty_keys = [] @deleted_keys = [] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#KEY_dirty? ⇒ Boolean #KEY_deleted? ⇒ Boolean
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
# File 'lib/attribute-kit/attribute_hash.rb', line 270 def method_missing(method, *args, &block) method_name = method.to_s case method_name when /(.*)_dirty?/ return @dirty_keys.include?($1) if self.has_key?($1) return @dirty_keys.include?($1.to_sym) if self.has_key?($1.to_sym) @deleted_keys.include?($1) || @deleted_keys.include?($1.to_sym) when /(.*)_deleted?/ @deleted_keys.include?($1) || @deleted_keys.include?($1.to_sym) else if self.class.superclass.instance_methods.map(&:to_sym).include?(:method_mising) super(method, *args, &block) else raise NoMethodError.new("undefined method '#{method_name}' for #{self}") end end end |
Instance Method Details
#[]=(k, v) ⇒ Object Also known as: store
Assigns a value to a key
81 82 83 84 85 86 87 88 |
# File 'lib/attribute-kit/attribute_hash.rb', line 81 def []=(k,v) if self[k].eql? v v else @dirty_keys << k super end end |
#clean_attributes(&block) {|dirty_attrs| ... } ⇒ Object
Calls a block with a hash of all keys, actions (:changed or :deleted), and current values (if :changed) of keys that have changed since the object was last marked clean. Marks the object as clean when it compiles the list of keys that have been modified.
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'lib/attribute-kit/attribute_hash.rb', line 232 def clean_attributes(&block) if !@dirty_keys.empty? dirty_attrs = {} @dirty_keys.uniq! dirty = @dirty_keys.dup @dirty_keys.clear deleted = @deleted_keys.dup @deleted_keys.clear while dirty.length > 0 do key = dirty.shift dirty_attrs[key] = [:changed, self[key]] end while deleted.length > 0 do key = deleted.shift dirty_attrs[key] = [:deleted, nil] end block.call(dirty_attrs) end end |
#clear ⇒ AttributeHash
Clear all contents of the object and mark it as dirty. An array of all removed keys is available via #deleted_keys.
195 196 197 198 199 |
# File 'lib/attribute-kit/attribute_hash.rb', line 195 def clear @deleted_keys += self.keys @dirty_keys.clear super end |
#delete(k) ⇒ Object
Delete a key-value pair
96 97 98 99 100 |
# File 'lib/attribute-kit/attribute_hash.rb', line 96 def delete(k) @deleted_keys << k @dirty_keys.delete(k) super end |
#delete_if {|key, value| ... } ⇒ AttributeHash
Delete keys matching an expression in the provided block
142 |
# File 'lib/attribute-kit/attribute_hash.rb', line 142 cond_deletion_method(:delete_if) |
#deleted_keys ⇒ Array
Returns the set of keys that have been deleted since the AttributeHash was last marked clean.
216 217 218 219 |
# File 'lib/attribute-kit/attribute_hash.rb', line 216 def deleted_keys @deleted_keys.uniq! @deleted_keys end |
#dirty? ⇒ Boolean
Check whether the contents of the object have changed since the last time clean_attributes was run.
203 204 205 |
# File 'lib/attribute-kit/attribute_hash.rb', line 203 def dirty? !(@dirty_keys.empty? && @deleted_keys.empty?) end |
#dirty_keys ⇒ Array
Returns the set of keys that have been modified since the AttributeHash was last marked clean.
209 210 211 212 |
# File 'lib/attribute-kit/attribute_hash.rb', line 209 def dirty_keys @dirty_keys.uniq! @dirty_keys + self.deleted_keys end |
#keep_if {|key, value| ... } ⇒ AttributeHash
Delete keys not matching an expression in the provided block
132 |
# File 'lib/attribute-kit/attribute_hash.rb', line 132 cond_deletion_method(:keep_if) |
#merge!(other_hash) {|key, oldval, newval| ... } ⇒ AttributeHash Also known as: update
Combine the contents of this object with the contents of the supplied hash, calling an optional supplied block to determine what value is used when there are duplicate keys. Without the block, values from the supplied hash will be used in the case of duplicate keys
168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/attribute-kit/attribute_hash.rb', line 168 def merge!(other_hash, &block) old_keys = self.keys overlapping_keys = old_keys.dup.keep_if {|v| other_hash.keys.include?(v)} r = super if block.nil? @dirty_keys += (self.keys - old_keys) + overlapping_keys else new_values = other_hash.keep_if {|k,v| overlapping_keys.include?(k)} @dirty_keys += (self.keys - old_keys) + (new_values.keep_if {|k,v| !self[k].eql?(v) }).keys end r end |
#reject! {|key, value| ... } ⇒ AttributeHash, Nil
Delete keys matching an expression in the provided block
111 |
# File 'lib/attribute-kit/attribute_hash.rb', line 111 cond_deletion_method(:reject!) |
#replace(other_hash) ⇒ AttributeHash
Replace the contents of this object with the contents of the supplied hash
148 149 150 151 152 153 154 155 |
# File 'lib/attribute-kit/attribute_hash.rb', line 148 def replace(other_hash) old_keys = self.keys r = super new_keys = self.keys @dirty_keys = new_keys @deleted_keys += (old_keys - new_keys) r end |
#select! {|key, value| ... } ⇒ AttributeHash, Nil
Delete keys not matching an expression in the provided block
122 |
# File 'lib/attribute-kit/attribute_hash.rb', line 122 cond_deletion_method(:select!) |
#shift ⇒ Array
Returns a key-value pair from the instance and deletes it.
186 187 188 189 190 |
# File 'lib/attribute-kit/attribute_hash.rb', line 186 def shift (k,v) = super @deleted_keys << k [k,v] end |