module Spicerack::HashModel

Provides on-demand synchronization between a `data' object and ActiveModel::Attributes

Public Instance Methods

define_field_methods(name) click to toggle source
# File lib/spicerack/hash_model.rb, line 33
def define_field_methods(name)
  define_method("#{name}?".to_sym) { data[name].present? }
  define_method("#{name}=".to_sym) do |value|  
    data[name] = value
    synchronize_attribute_from_datastore(name)
  end
  define_method(name) do
    synchronize_attribute_from_datastore(name)
    attribute(name)
  end
end
field(name, type = Type::Value.new, **options) click to toggle source
# File lib/spicerack/hash_model.rb, line 26
def field(name, type = Type::Value.new, **options)
  name = name.to_s
  _fields << name
  attribute(name, type, **options)
  define_field_methods(name)
end
inherited(base) click to toggle source
Calls superclass method
# File lib/spicerack/hash_model.rb, line 19
def inherited(base)
  base._fields = _fields.dup
  super
end

Private Instance Methods

synchronize_attribute_from_datastore(name) click to toggle source

The data object can be anything from a normal hash to a hash-like object backed by redis.

# File lib/spicerack/hash_model.rb, line 49
def synchronize_attribute_from_datastore(name)
  value_from_datastore = data[name]
  value_from_attribute = attribute(name)
  return if value_from_datastore == value_from_attribute
  
  value = value_from_datastore || value_from_attribute
  
  # Otherwise, the dataset is value takes priority and is written as the attribute value
  # ActiveModel changed the interface to this method between Rails 6.0 and 6.1
  # This method is a patch which allows this class to work with either version
  # Once support for pre rails 6.0 is sunset this should likely be removed
  if respond_to?(:_write_attribute, true)
    _write_attribute(name, value)
  else
    write_attribute(name, value)
  end
end