Store gives you a thin wrapper around serialize for the purpose of storing hashes in a single column. It's like a simple key/value store baked into your record when you don't care about being able to query that store outside the context of a single record.
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.
Make sure that you declare the database column used for the serialized store as a text, so there's plenty of room.
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 - If you are using PostgreSQL specific columns like
hstore
or json
there is no need for the
serialization provided by store
. Simply 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.
Examples:
class User < ActiveRecord::Base store :settings, accessors: [ :color, :homepage ], coder: JSON end u = User.new(color: 'black', homepage: '37signals.com') u.color # Accessor stored attribute 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' # Add additional accessors to an existing store through store_accessor class SuperUser < User store_accessor :settings, :privileges, :servants end
The stored attribute names can be retrieved using
stored_attributes
.
User.stored_attributes[:settings] # [:color, :homepage]
Overwriting default accessors
All stored values are automatically available through accessors on the
Active Record 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 < ActiveRecord::Base # 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