Simple Rails App Configuration Settings

Virtually every application needs a solid way to organize and store application level configuration settings. There are a slew of gems out that purport to do the work for you, but here is a solution that you can implement in short order, with no external dependencies.

Declare

We'll first create a YAML file to store our application configuration settings, as shown below.

config/application.yml

defaults: &defaults
  email: dev@example.com
  secret: foo123

development:
  <<: *defaults

test:
  <<: *defaults
  email: test@example.com

production:
  <<: *defaults
  email: info@example.com
  secret: 321oof

Note the different sections corresponding to your different Rails environment modes, which each inherit from the defaults section. eg) The value of email in development would be dev@example.com. Also note that values should be stored as strings. Simply quote values if you are unsure if a value would be treated as a string.

IMPORTANT: As this file is good candidate for storage of sensitive information such as passwords, API keys and such, we'll want to be sure that this file does NOT get committed to version control. This is particularly important if your Git repo is public, but is good practice for private repo's too. You can accomplish this by adding the file reference to your .gitignore, as shown below.

.gitignore

config/application.yml  

Along these lines, it is a good practice to commit a copy of this file, as application.example.yml, albeit with values replaced with key documentation.

Load

Next we need to load our variables during application startup. We do this with a single line of code placed at a strategic position within config/application.rb, as shown below. The variables are loaded at this specific location and time so that they are available for use within Rails initializers - a common use case.

The code works by loading the variables from the section of config/application.yml matching the current Rails environment (eg - development, test, production) then merging them into the existing the ENV values using the ENV.update method.

If the file does not exist, or if there is an error parsing the file, the rescue clause returns an empty hash, which is then merged into the existing ENV.

config/application.rb - You just need the middle lines… but you already knew that.

if defined?(Bundler)
  ...
end

# Load application ENV vars and merge with existing ENV vars. Loaded here so can use values in initializers.
ENV.update YAML.load_file('config/application.yml')[Rails.env] rescue {}

module Whatever
  class Application < Rails::Application
    ...

Use

The most common way to use these variables in your code is to simply access them directly in the ENV, using the hash-like syntax, as shown below. You may also want to have a look at the ENV class reference for other available methods.

puts ENV['email']

secret = ENV['secret']
puts secret

Heroku? Yep!

As config/application.yml does not get committed to version control, Heroku obviously won't be able to load and initialize any variables from it. This won't break things outright due to the rescue {} clause described above. We do however need to set the ENV variables on Heroku somehow. Fortunately this quite easy using the Heroku Toolbelt.

# View existing config vars
heroku config

# Add/update config vars
heroku config:add email=info@example.com secret=321oof

# Add these if they do not already exist (using whatever mode you wish)
heroku config:add RAILS_ENV=production RACK_ENV=production

Alternatives

There are a bunch of gems out there for handling this type of functionality too, some having more bells and whistles. I typically however don't find the need to add an external dependency when the solution is so straightforward.

What is your preferred method of accomplishing this task?


QuickLeft closeicon

Let's Build Your Project

Phone: 303.242.5536
Quick Left HQ
902 Pearl St.
Boulder, CO 80302
Quick Left San Francisco
665 3rd St.
#150
San Francisco, CA 94107
Quick Left Portland
529 SW 3rd Ave.
2nd Floor
Portland, OR 97204
Quick Left Denver
Galvanize
1062 Delaware St.
Denver, CO 80204