YAML Configuration in Ruby with Settingslogic

A few months ago, I came across the Settingslogic gem. I wish I’d discovered it years ago.

Until then, I’d found myself manually handling configuration and settings via raw access to YAML files. This meant I was repeatedly writing code like the follow to handle my various needs:

require 'fedora/connection'
config_file = Rails.root.join('config', 'fedora.yml').to_s
if not File.exist?(config_file)
  raise "You need a config/fedora.yml file. Try starting with config/fedora.example.yml if you need a sample to start from."
configuration = HashWithIndifferentAccess.new(YAML.load_file(config_file))[Rails.env]

All of that checking for the config file’s presence, parsing it with YAML, extracting and passing around the configuration, testing it… blah. Any individual operation is simple and straightforward, but performing all of those operations together, multiple times, is irritating and prone to errors.

Settingslogic is awesome. Now instead of the above code, I can write code like this to grab my settings:

class SystemConfiguration < Settingslogic
  source "#{Rails.root}/config/system_config.yml"
  namespace Rails.env

And code like this to access them:

def self.playlist_id

# or

config.api_key = SystemConfiguration.airbrake.api_key

# or

GOOGLE_ANALYTICS_TRACKING_ID = SystemConfiguration.google_analytics.tracking_id

Since SystemConfiguration is a real object, setting it up for testing is super easy as well:

SystemConfiguration.stub_chain(:youtube, :playlist, :id) { '1234' }

Yay! No more futzing with YAML configuration directly, passing configuration all over the place to simplify testing, worrying as much about missing files, etc. Settingslogic is straightforward and effective — and a great example of Ruby abstraction done well.

I hope you find Settingslogic as helpful as I have!

  • Daniel Kehoe says:

    What do you think of the figaro gem? Sets up a configuration YAML file using ENV variables. I wrote about it in my article on Rails Environment Variables.

  • Comments are closed.