diff options
Diffstat (limited to 'activerecord/lib/active_record/store.rb')
-rw-r--r-- | activerecord/lib/active_record/store.rb | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb index d5910df891..ce2ea85ef9 100644 --- a/activerecord/lib/active_record/store.rb +++ b/activerecord/lib/active_record/store.rb @@ -10,15 +10,21 @@ module ActiveRecord # 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+. + # + # String keys should be used for direct access to virtual attributes because of most of the coders do not + # distinguish symbols and strings as keys. + # # Examples: # # class User < ActiveRecord::Base - # store :settings, accessors: [ :color, :homepage ] + # 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 + # u.color # Accessor stored attribute + # u.settings['country'] = 'Denmark' # Any attribute, even if not specified with an accessor # # # Add additional accessors to an existing store through store_accessor # class SuperUser < User @@ -26,24 +32,27 @@ module ActiveRecord # end module Store extend ActiveSupport::Concern - + module ClassMethods def store(store_attribute, options = {}) - serialize store_attribute, Hash + serialize store_attribute, options.fetch(:coder, Hash) store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors end def store_accessor(store_attribute, *keys) - Array(keys).flatten.each do |key| + keys.flatten.each do |key| define_method("#{key}=") do |value| - send(store_attribute)[key] = value + send("#{store_attribute}=", {}) unless send(store_attribute).is_a?(Hash) + send(store_attribute)[key.to_s] = value + send("#{store_attribute}_will_change!") end - + define_method(key) do - send(store_attribute)[key] + send("#{store_attribute}=", {}) unless send(store_attribute).is_a?(Hash) + send(store_attribute)[key.to_s] end end end end end -end
\ No newline at end of file +end |