A while back in Railscast #85 Ryan Bates demonstrated how to add a YAML-based configuration file to a Rails application. You start with the configuration file – say RAILS_ROOT/config/app_config.yml – containing your configuration data:

# config/app_config.yml
development:
  key1: development value 1
test:
  key1: test value 1
production:
  key1: production value 1

And then you load the file from an initializer – say RAILS_ROOT/config/initializer/load_config.rb – containing the following:

# config/initializers/load_config.rb
APP_CONFIG = YAML.load_file("#{Rails.root}/config/app_config.yml")[Rails.env]

And from then on a Hash named APP_CONFIG will be available throughout your application containing the configuration specific to the environment in which your application is running, i.e., development, test or production.

But what if you want to dynamically configure one or more values in your configuration file? Other YAML files loaded by Rails such as fixture files or database.yml are processed through ERB before being loaded. Wouldn’t it be nice to be able to do the same in your application configuration file?

# config/app_config.yml
development:
  key1: <%= # ruby code ... %>
test:
  key1: <%= # ruby code ... %>
production:
  key1: <%= # ruby code ... %>

As it is Rails will not process those ERB snippets, but you can change that with one small change to your initializer:

# config/initializers/load_config.rb
APP_CONFIG = YAML.load(ERB.new(File.read("#{Rails.root}/config/app_config.yml")).result)[Rails.env]

Now, instead of loading the file directly, YAML loads the string returned by ERB\#result which will contain the contents of the app_config.yml after the ERB snippets have been evaluated.