views:

187

answers:

4

I'm aware of YAML and plugins like rails-settings, but neither of these is useful for configuration settings that need to be changed in real time.

For instance, say I have MAX_ALLOWED_REGISTERED_USERS set at 2000, but I want to up it to 2300. With a typical "configuration" or YAML solution, this would involve changing a config file and redeploying. I'd prefer a database-backed RESTful approach where I could just change a key/value pair.

Thoughts?

A: 

Moneta may suit your needs, it is a key/value storage system with configurable backends:

http://yehudakatz.com/2009/02/12/initial-release-of-moneta-unified-keyvalue-store-api/

pantulis
+1  A: 

I use a Configuration model similar to this:

# == Schema Information
# Schema version: 20081015233653
#
# Table name: configurations
#
#  id          :integer         not null, primary key
#  name        :string(20)      not null
#  value       :string(255)
#  description :text
#

class InvalidConfigurationSym < StandardError; end

class Configuration < ActiveRecord::Base
  TRUE  = "t"
  FALSE = "f"

  validates_presence_of   :name
  validates_uniqueness_of :name
  validates_length_of     :name, :within => 3..20 

  # Enable hash-like access to table for ease of use.
  # Raises InvalidConfigurationSym when key isn't found.
  # Example:
  #   Configuration[:max_age] => 80
  def self.[](key)
    rec = self.find_by_name(key.to_s)
    if rec.nil?
      raise InvalidConfigurationSym, key.to_s
    end
    rec.value
  end

  # Override self.method_missing to allow
  # instance attribute type access to Configuration
  # table. This helps with forms.
  def self.method_missing(method, *args)
    unless method.to_s.include?('find') # skip AR find methods
      value = self[method]
      return value unless value.nil?
    end
    super(method, args)
  end
end

Here's how I use it:

class Customer < ActiveRecord::Base
  validate :customer_is_old_enough?

  def customer_is_old_enough?
    min_age = Date.today << (Configuration[:min_age].to_i * 12)
    self.errors.add(:dob, "is not old enough") unless self.dob < min_age
  end
end

One thing I'm not quite happy with is having to call #to_i like in the sample, but since it works for me so far, I haven't put too much thought in redesigning it.

Matt Haley
A: 

If you're running a multi-server application, mutable configuration needs to be stored centrally (unless you don't mind different servers having different configurations)

As posted above, Moneta is a decent choice, though I'd wager mecached is more widely-deployed alongside Rails applications.

Duncan Beevers
A: 

Here's a naive suggestion: make a DB table, migration and ActiveRecord-model and treat your config like any other entity in the database, minus a controller and view. Just a thought.

Perhaps put this data in memcached, and have it expire frequently enough if you are too worried about disturbing the database.

Roboprog
Doh! I basically duplicated Matt Haley's answer. Well, I guess my answer is a summary of all the code he launched into without telling the lazy / casual reader (me) where he was going.
Roboprog