= DoesKeyValue NoSQL-like key value stores in SQL-backed ActiveRecord objects. Arbitrary keys behave like dynamic, indexable, searchable first-order attributes. == Deprecation Notice DoesKeyValue is undergoing a substantial API change in order to better support new features and alter the approach to previously-included features. The "old" gem versions will have number in the v0.2.* series and are maintained (though only for major bugfixes) on the {"albus" branch}[https://github.com/awexome/doeskeyvalue/tree/albus] in the repository. Going forward, new work on the gem will be of the v0.9.* version series and will be completed in {"bellatrix" branch}[https://github.com/awexome/doeskeyvalue/tree/bellatrix] and made available in master. When ready, the new "bellatrix" API will be released as a public gem with v0.9.0, but until then, users can live on the edge by referencing this repository (master or bellatrix branches) in their Gemfiles. This documentation refers to only the new/v0.9+ branch and its corresponding API. == Installation Tried and true: gem install doeskeyvalue And add a gem dependency to your Gemfile: gem "doeskeyvalue" == Column-Based Storage Example In any ActiveRecord model in which you'd like to have key-value support, you simply declare your intention to declare keys: does_keys :column=>"settings" In this invocation, "settings" is the name of TEXT or BLOB field on your model's database table. Think of it as something you'd typically serialize, but would prefer solid accessor and finding behavior on. Add keys to your document field individually like so: has_key :email # Default type is string has_key :uid, :type=>:integer # But type can be overidden easily has_key :city, :default=>"Awesomeville" # You can also declare default values This adds email, uid, and city fields to your record. You can use these fields just like regular columns on your ActiveRecord object, but they're happily stored within your TEXT/BLOB column at the database level. Check it out: mod = Model.new mod.email = "me@awexo.me" => "me@awexo.me" mod.email => "me@awexo.me" You can see the serialized key-value structure at any time, as well. Just access your old field: mod.settings => {:email=>"me@awexo.me"} === Indexes and Searchability By default, all keys specified in column-based storage also have indexes which provide scopes and searchability. This behavior, however, requires the addition of an key index database table, which you can generate on the command line: > rails generate doeskeyvalue > rake db:migrate This will add a +key_value_index+ table to your database, which will serve as an application-wide index and cache of your declared keys. Key values you modify on your objects are stored/cached within the +key_value_index+ table, which is used in lookups. For each key, a default scope of the form "with_KEYNAME" is provided for your use: Model.with_email("foo@bar.com") => [] Model.with_email("me@awexo.me") => [#"me@awexo.me"}, ...>] If you'd prefer to not have this searchability, you can forgo the creation of an index and related scope for any of your keys, like so: has_key :email, :index=>false # Deny index creation (default setting for index is true) Naturally, if all of your keys omit an index, you will not require the +key_value_index+ table in your project. == Table-Based Storage Example For larger key sets, you may find it advantageous to move your key-value storage into a separate database table altogether, instead of the baked-in serialized TEXT/BLOB column. You can do this quite easily by using a different flag in your initialization call: does_keys :table=>"user_preferences" In this example, we're storing our key-value pairs as their own independent rows within the user_preferences database table. You declare keys and manipulate values in exactly the same way as before: has_key :bgcolor, :default=>"blue" has_key :birthday, :type=>:datetime has_key :likes_ice_cream, :type=>:boolean, :default=>true mod.likes_ice_cream => true mod.likes_ice_cream = false => false mod.bgcolor => "blue" However, unlike with column-based storage, these values are immediately written to the table specified in the invocation (in this case, +user_preferences+). You will need to generate your separate key value indexes using the generator, while providing a table name: > rails generate doeskeyvalue user_preferences > rake db:migrate All keys using the separate table-based storage approach are automatically indexed. Values are read directly from the supporting index table. If desired, multiple models can freely store their values in a single table. This may be desired for locality of all settings across a varieties of classes. You could, for instance, create one +preferences+ table, which collects key values from User, Account, and Post models. For each class, the invocation to +does_keys+ is the same. Simple! == Copyright Copyright (c) 2012 Awexome Labs, LLC. http://awexomelabs.com/