In any large software project there is a concept of setting or configuration. In .NET, there is the System.Configuration class. Rails doesn’t have anything like this, but Most of the time, I have some need to roll my own class for this I recently have been using a setting class I created that loads settings from the database and stores them as constants on a class called ‘Setting’.
My goals were:
1. No repeated hits to the database just to access a property, except occasional reloads for an update to a setting in the database.
2. Runtime errors if a setting doesn’t exist. No returning ‘nil’ if a setting is mistyped.
3. Ability to update settings across multiple machines, in a reasonable amount of time. In this case, five minutes is reasonable.
This code is in lib/setting.rb (i’m still not sure why but i couldn’t get this to work when inside the main setting.rb file in the model directory):
class Setting
def self.load_settings
Setting.find(:all).each do |s|
logger.debug "Loaded Setting: #{s.name}: #{s.value}"
Setting.instance_eval do
isnum = ((s.value.to_i.to_s == s.value.to_s) rescue false)
eval "def #{s.name}\\n#{s.value}\\nend" if isnum
eval "def #{s.name}\\n\"#{s.value}\"\\nend" unless isnum
end
end
end
self.load_settings
end
Here’s the super simple migration in the pre-rails-2.0 migration format:
class CreateSettings < ActiveRecord::Migration
def self.up
create_table "settings", :force => true do |t|
t.column "name", :string, :limit => 50, :default => "", :null => false
t.column "value", :string, :default => "", :null => false
end
add_index "settings", ["name"], :name => "settings_name_index"
end
def self.down
drop_table :settings
end
end
Here’s the ‘main’ setting class:
class Setting < ActiveRecord::Base serialize :value end
In environment.rb, in order to reload the settings every five minutes:
require 'thread'
Thread.new { loop {sleep(300); Setting.load_settings rescue nil } }
I’m searching for something like this: Fast, nested key-value pairs, using db-store, store arbitrary ruby objects (serialize via Marshal), preferably cached, native ruby api..
Something akin to bdb or Tokyo Cabinet, but on ActiveRecord / Ruby steroids of course.
Maybe associative array activerecord will show more hits. Maybe what I’m looking for is really Hibernate, or some kind of ORM, but I’m having a hard time finding it for sure.
Use Case: For persistence of objects with minimal reads (cache) and writes (partly serializes)
More searching..
Of course ORM gives alot of results, now for some serious reading..
Even more..
Invented before: nosql, schemaless data and document dbs or whatever it was called. Neat concepts and I should be able to be find some wheel, like friendly or similar to that.
After some more searching, unable to locate a general solution.
Am thinking I could loop over the nested hash / arrays myself and attach / convert ActiveRecord objects to the elements or create an appropriate subclass. Then all I’d need to do is call save() if it has_changed() or preferably mass updating them using a temporary table.
It’ll be general enough to act as a general solution for my project at least. Just surprised I cannot find this implemented already for such unstructured and non-formal data mapped onto RDBMS.