module NoBrainer::Document::Store
Store
gives you a way for storing hashes in a single field with accessors to the Hash keys. It is a portage of the ActiveRecord::Store which make gems using it compatible with NoBrainer
.
You can then declare accessors to this store that are then accessible just like any other attribute 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
).
You can set custom coder to encode/decode your serialized attributes to/from different formats. JSON, YAML, Marshal are supported out of the box. Generally it can be any wrapper that provides load
and dump
.
NOTE: The .store method is here for compatibility reason, but you should use .store_accessor instead to generate the accessor methods. Be aware that these columns use a string keyed hash and do not allow access using a symbol.
NOTE: The default validations with the exception of uniqueness
will work.
Examples:
class User include NoBrainer::Document store :settings, accessors: [ :color, :homepage ], coder: JSON store :parent, accessors: [ :name ], coder: JSON, prefix: true store :spouse, accessors: [ :name ], coder: JSON, prefix: :partner store :settings, accessors: [ :two_factor_auth ], suffix: true store :settings, accessors: [ :login_retry ], suffix: :config end u = User.new(color: 'black', homepage: '37signals.com', parent_name: 'Mary', partner_name: 'Lily') u.color # Accessor stored attribute u.parent_name # Accessor stored attribute with prefix u.partner_name # Accessor stored attribute with custom prefix u.two_factor_auth_settings # Accessor stored attribute with suffix u.login_retry_config # Accessor stored attribute with custom suffix u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor # There is no difference between strings and symbols for accessing # custom attributes 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 store_accessor :parent, :birthday, prefix: true store_accessor :settings, :secret_question, suffix: :config end
The stored attribute names can be retrieved using .stored_attributes.
User.stored_attributes[:settings] #=> [:color, :homepage, :two_factor_auth, :login_retry]
Overwriting default accessors¶ ↑
All stored values are automatically available through accessors on the NoBrainer
Document
object, but sometimes you want to specialize this behavior. This can be done by overwriting the default accessors (using the same name as the attribute) and calling super
to actually change things.
class Song include NoBrainer::Document # Uses a stored integer to hold the volume adjustment of the song store :settings, accessors: [:volume_adjustment] def volume_adjustment=(decibels) super(decibels.to_i) end def volume_adjustment super.to_i end end
Attributes
Private Instance Methods
# File lib/no_brainer/document/store.rb, line 235 def read_store_attribute(store_attribute, key) # :doc: StringKeyedHashAccessor.read(self, store_attribute, key) end
# File lib/no_brainer/document/store.rb, line 239 def write_store_attribute(store_attribute, key, value) # :doc: StringKeyedHashAccessor.write(self, store_attribute, key, value) end