diff options
Diffstat (limited to 'activerecord/lib/active_record/store.rb')
-rw-r--r-- | activerecord/lib/active_record/store.rb | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb index 6dbc977f9a..3537e2d008 100644 --- a/activerecord/lib/active_record/store.rb +++ b/activerecord/lib/active_record/store.rb @@ -17,8 +17,8 @@ module ActiveRecord # 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}[rdoc-ref:rdoc-ref:ClassMethods#store]. + # NOTE: If you are using structured database data types (eg. PostgreSQL +hstore+/+json+, or MySQL 5.7+ + # +json+) there is no need for the serialization provided by {.store}[rdoc-ref:rdoc-ref:ClassMethods#store]. # Simply use {.store_accessor}[rdoc-ref:ClassMethods#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. @@ -31,10 +31,18 @@ module ActiveRecord # # class User < ActiveRecord::Base # 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') + # 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 @@ -44,11 +52,13 @@ module ActiveRecord # # 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}[rdoc-ref:rdoc-ref:ClassMethods#stored_attributes]. # - # User.stored_attributes[:settings] # [:color, :homepage] + # User.stored_attributes[:settings] # [:color, :homepage, :two_factor_auth, :login_retry] # # == Overwriting default accessors # @@ -81,19 +91,40 @@ module ActiveRecord module ClassMethods def store(store_attribute, options = {}) serialize store_attribute, IndifferentCoder.new(store_attribute, options[:coder]) - store_accessor(store_attribute, options[:accessors]) if options.has_key? :accessors + store_accessor(store_attribute, options[:accessors], options.slice(:prefix, :suffix)) if options.has_key? :accessors end - def store_accessor(store_attribute, *keys) + def store_accessor(store_attribute, *keys, prefix: nil, suffix: nil) keys = keys.flatten + accessor_prefix = + case prefix + when String, Symbol + "#{prefix}_" + when TrueClass + "#{store_attribute}_" + else + "" + end + accessor_suffix = + case suffix + when String, Symbol + "_#{suffix}" + when TrueClass + "_#{store_attribute}" + else + "" + end + _store_accessors_module.module_eval do keys.each do |key| - define_method("#{key}=") do |value| + accessor_key = "#{accessor_prefix}#{key}#{accessor_suffix}" + + define_method("#{accessor_key}=") do |value| write_store_attribute(store_attribute, key, value) end - define_method(key) do + define_method(accessor_key) do read_store_attribute(store_attribute, key) end end |