0.0
No commit activity in last 3 years
No release in over 3 years
NoSQL-like key value stores in SQL-backed ActiveRecord objects. Arbitrary keys behave like dynamic, indexable, searchable first-order attributes.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.2.1
~> 1.8.4
~> 3.12
>= 2.11.0
>= 1.3.6

Runtime

~> 3.2.0
~> 1.2.0
 Project Readme

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 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 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")
=> [#<User id: 1, ..., settings: {"email"=>"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 © 2012 Awexome Labs, LLC. awexomelabs.com/