aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/store.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2011-10-13 16:23:48 -0500
committerDavid Heinemeier Hansson <david@loudthinking.com>2011-10-13 16:24:22 -0500
commit85b64f98d100d37b3a232c315daa10fad37dccdc (patch)
treee1f4b621240502e7cb9b5530495840c2e8315c52 /activerecord/lib/active_record/store.rb
parent8f11d53506ea7ef2fd4cd28581f5eedd9be9e570 (diff)
downloadrails-85b64f98d100d37b3a232c315daa10fad37dccdc.tar.gz
rails-85b64f98d100d37b3a232c315daa10fad37dccdc.tar.bz2
rails-85b64f98d100d37b3a232c315daa10fad37dccdc.zip
Added ActiveRecord::Base.store for declaring simple single-column key/value stores [DHH]
Diffstat (limited to 'activerecord/lib/active_record/store.rb')
-rw-r--r--activerecord/lib/active_record/store.rb49
1 files changed, 49 insertions, 0 deletions
diff --git a/activerecord/lib/active_record/store.rb b/activerecord/lib/active_record/store.rb
new file mode 100644
index 0000000000..d5910df891
--- /dev/null
+++ b/activerecord/lib/active_record/store.rb
@@ -0,0 +1,49 @@
+module ActiveRecord
+ # 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 backed 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.
+ #
+ # Examples:
+ #
+ # class User < ActiveRecord::Base
+ # store :settings, accessors: [ :color, :homepage ]
+ # 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
+ #
+ # # Add additional accessors to an existing store through store_accessor
+ # class SuperUser < User
+ # store_accessor :settings, :privileges, :servants
+ # end
+ module Store
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ def store(store_attribute, options = {})
+ serialize store_attribute, 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|
+ define_method("#{key}=") do |value|
+ send(store_attribute)[key] = value
+ end
+
+ define_method(key) do
+ send(store_attribute)[key]
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file