Config So Simple Your Mama Could Use It

Tonight, Kastner asked me if I had anything to do some simple configuration for something he was working on. I’ve got a simple module and yaml file that I’ve been using so I gist’d it. It then occurred to me that I might as well share it here too.

The Yaml

Below is an example of the yaml file. Basically, I setup some defaults and then customize each environment as needed.

DEFAULTS: &DEFAULTS
  email: no-reply@harmonyapp.com
  email_signature: |
    Regards,
    The Harmony Team
 
development:
  domain: harmonyapp.local
  <<: *DEFAULTS
  
test:
  domain: harmonyapp.com
  <<: *DEFAULTS
 
production:
  domain: harmonyapp.com
  <<: *DEFAULTS

The Module

The module can read and write to the config and even loads the Yaml file the first time you try to read a configuration key.

module Harmony
  # Allows accessing config variables from harmony.yml like so:
  # Harmony[:domain] => harmonyapp.com
  def self.[](key)
    unless @config
      raw_config = File.read(RAILS_ROOT + "/config/harmony.yml")
      @config = YAML.load(raw_config)[RAILS_ENV].symbolize_keys
    end
    @config[key]
  end
  
  def self.[]=(key, value)
    @config[key.to_sym] = value
  end
end

If I wanted to get the domain, I would do the following:

Harmony[:domain]

Nothing fancy, but it gets the job done. I just drop the yaml file in config/ and the module in lib/. Obviously, you would rename the module and yaml file to whatever constant you want, such as App or something related to your application’s name. I know there are gems and plugins to do configuration, but when something this simple gets the job done, I figure why bother.

What do you all use for app configuration? What do you like about what you use?

10 Comments

  1. Angel N. Sciortino Angel N. Sciortino

    Nov 10, 2009

    I have a very similar setup, except it checks for a local config file, which would be ignored in git. If it doesn’t exist, it loads the default config.

    
    if File.exist?(RAILS_ROOT + "/config/config.local.yml")
      raw_config = File.read(RAILS_ROOT + "/config/config.local.yml")
    else
      raw_config = File.read(RAILS_ROOT + "/config/config.yml")
    end
    
  2. Hello!
    Sometimes I use kind of config like you’ve explained. I also like to go with configatron to easy setup of the application.
    http://github.com/markbates/configatron

    Cheers, Carlos.

  3. mathieul mathieul

    Nov 10, 2009

    Thanks for this post!

    There is another dead simple solution presented by Ryan Bates in the Railscast #85 (http://railscasts.com/episodes/85-yaml-configuration-file) where he loads the configuration in a global constant from an initializer.

  4. Interesting to see others are using something similar.

    @mathieul – Ah, yeah, I forgot about that.

  5. Hi John, this is exactly what we do in OtherInbox and it works very well. We also use a custom version of the Settings plugin for variables that need to be changed while in production (http://beautifulpixel.com/svn/plugins/settings)

    -Mike

  6. Another vote for configatron here.

  7. Check out settingslogic. http://www.github.com/binarylogic/settingslogic

  8. I actually do something similar that also works with Heroku. I linked to it from your article earlier this week already, but it’s relevant to this post, too :)

  9. I use OStruct and YAML.

    require 'ostruct'
    require 'yaml'
    settings = OpenStruct.new(YAML.load_file("#{RAILS_ROOT}/config/settings.yml"))
    env_settings = settings.send(RAILS_ENV)
    settings.common.update(env_settings) unless env_settings.nil?
    ::Settings = OpenStruct.new(settings.common)
    common: &amp;common
      app_name: App
    development:
      &lt;&lt;: *common
    test:
      &lt;&lt;: *common
    production:
      &lt;&lt;: *common

    Then you can use Settings.app_name

  10. @Steve – The only problem with OpenStruct is it doesn’t do nested hashes. If you nested any of the config you would have to do Settings.nested[:deeper_nested]. You might want to checkout mash which will do nested hashes.

Sorry, comments are closed for this article to ease the burden of pruning spam.

About

Authored by John Nunemaker (Noo-neh-maker), a programmer who has fallen deeply in love with Ruby. Learn More.

Projects

Flipper
Release your software more often with fewer problems.
Flip your features.