Storing System Preferences in the Database
Here is a simple way to store system preferences in the database for a Ruby on Rails application. This simple solution offers no caching, so accessing the same preference many times will result in many database request. Suggestions for per request caching are welcomed.Using the code bellow, one can access preferences like this :
admin_email= Preference["admin_email"]First, let's start with a migration that will create a table in which we can store many types of preferences :
class CreatePreferences < ActiveRecord::MigrationNow, we create the model. Because we want to be able to get many types of preferences (and eventually validate their value in different ways), we create a base Preference class and many subclasses for all the types of preferences we want to have. Some subclass will override the value and value= methods to convert the value to the proper type :def self.upendcreate_table :preferences do |t|endt.column :setting, :stringend
t.column :type, :string
t.column :value, :string
def self.downdrop_table :preferencesend
class Preference < ActiveRecord::BaseNote that we could add validation for the value attribute in UrlPreference and EmailPreference to validate the format of the value.validates_presence_of :settingend
def self.[](setting)setting= self.find_by_setting(setting)end
setting.nil? ? nil : setting.value
class UrlPreference < Preference
end
class EmailPreference < Preference
end
class StringPreference < Preference
end
class IntegerPreference < Preferencedef value()endself[:value].nil? ? nil : self[:value].to_iend
def value=(v)self[:value]= v.nil? ? nil : v.to_send
1 comment:
How about adding caching so you only hit the db once if the params don't change
class Preference < ActiveRecord::Base
validates_presence_of :setting
@@cached_data = {}
def self.[](setting)
if @@cached_data[setting]
res = @@cached_data[setting]
else
res = self.retrieve(setting)
@@cached_data[setting] = res if res
end
res
end
def self.retrieve(setting)
setting= self.find_by_setting(setting)
setting.nil? ? nil : setting.value
end
end
Post a Comment