ActiveRecord - Simple Key Value Store
Over the last few weeks I have been playing with the idea of having a simple database backed key value store using Rails ActiveRecord. The ActiveRecord class should act like a singleton where arbitrary keys can be set with a value of any type (simple values, hashes, arrays or complex objects). I have come up with the idea of using method missing to set and retrieve the key / value pair where the value's are saved as yaml and then cast back to the correct type when retrieved.
class Application < ActiveRecord::Base set_table_name "application_settings" def self.method_missing(method, *args, &block) return self.send method, *args, &block if self.respond_to? method method_name = method.to_s if method_name =~ /=/ return self.set method_name.gsub("=", ""), args.first else return self.get method_name end end private def self.get setting entry = Application.where(:key => setting).first entry.nil? ? nil : YAML.load(entry.value) end def self.set key, value setting = Application.where(:key => key).first || Application.new(:key => key) setting.update_attribute(:value, value.to_yaml) end end
Below is the migration needed to setup the database table for your application settings class.
class CreateApplicationSettings < ActiveRecord::Migration def up create_table :application_settings, :id => false do |t| t.string :key t.text :value t.timestamps end add_index :application_settings, :key, :unique => true end def down drop_table :application_settings end end
Using the class it is possible to set a value to any arbitrary key by calling the setting name setter method just like it is a defined class attribute.
Application.some_arbitrary_setting = 12903 Application.my_hash_foo = { :foo => "bar" }
To retrieve the setting make a method call to the key name as if it were a defined class attribute.
Application.some_arbitrary_setting => 12903 Application.my_hash_foo => {:foo=>"bar"}