Making Configuration Files with YAML: Revised

So back in July 2007 I posted a blog on making configuration files with YAML, and I’ve been noticing a lot of readership on the old article. Because it seems that a lot of people are reading it I felt it was important to show how I apply this nowadays.

First I put my config.yml file within the /config/ directory within my Rails application. It looks something like this:

development: &non_production_settings
  :google_analytics:
    :api_key: "[Enter Google ID]"
  :site:
    :title: "[Title]"
    :address: "http://localhost:3000/"

test:
  <<: *non_production_settings

production:
  :google_analytics:
    :api_key: "[Enter Google ID]"
  :site:
    :title: "[Title]"
    :address: "[Address]"

Then, I create a new file called load_config.rb within the /config/initializers directory. You can name the file whatever you want – that’s just what I call it. This is where the actually YAML loading is going to happen – and this is what it looks like:

raw_config = File.read(RAILS_ROOT + "/config/config.yml")
APP_CONFIG = YAML.load(raw_config)[RAILS_ENV]

Now any time I want to all one of these variables I just call it like:

<%= APP_CONFIG[:site][:title] %>
About these ads

12 Comments on “Making Configuration Files with YAML: Revised”

  1. Jason says:

    Thanks for the quick yaml config how-to. I am new to RoR and this was exactly what I was looking for.

  2. […] post info By Tim Categories: Ruby and Ruby on Rails Update: A newer version of how I load YAML into configuration files in my projects can be found here. […]

  3. cheapRoc says:

    AppConfig = OpenStruct.new(YAML.load_file(“#{RAILS_ROOT}/config/app_config.yml”)[Rails.env].symbolize_keys) if require ‘ostruct’

    So you can do something like…

    AppConfig.site_title

    Not sure how it works with your nested Yaml config file though.

  4. jyoseph says:

    This is freaking awesome. I’m also a rails newb and this was drop dead simple.

    Question, the file will only be read once right, when the app starts? (as opposed to every request)

    • Tim Knight says:

      jyoseph,

      Glad you liked it! I hope it is helpful for you. The code is run as an initializer so it runs on application initialization storing the information into a constant. While it might run with each request in development mode (can’t recall) it should only run on initialization during production mode.

  5. jyoseph says:

    Thanks for the clarification on that, I’m actually more excited than I should be about this, hah! It allowed me to have some app-specific settings that I would not want to commit to github. I saw some other solutions (gems/plugins) but all seemed too heavy for what I needed. Thanks again!

    • Tim Knight says:

      You’ll actually find something like this in most larger Rails applications (from my experience). It’s great for API keys and all the various configuration details that might differ between the multiple environments. Ryan Bates (of Railscasts fame) has a similar config file system in his nifty_generators nifty_config feature at https://github.com/ryanb/nifty-generators. Enjoy!

  6. Dc says:

    Hi, this is a great article for newbies like me. I’ve actually looked all over and this seems to be the best resource for understanding.

    I have a few questions if you don’t mind to clear some things up.

    First off, do you include config.yml in your .gitignore file so that it is private and not tracked and when pushing to a remote repo on github? (for private things like API or s3 keys)

    And if you do add config.yml to your gitignore file. When pushing up to a cloud server such as heroku, how does heroku have contact with your config.yml file if it’s not on github.

    Thanks again for the helpful post!

    • Tim Knight says:

      Hi Dc,

      That’s a really good question. When it comes to whether or not you would add config.yml to your .gitignore personally I feel it just depends. It depends of course first on what the material is you are using in your configuration and secondly it depends on if you repository is public or private. If you do leave it out I would suggest creating a config.sample.yml with test data in it so other contributors on the project can understand the structure of the file. When it comes to deployment I would say that if you are running a public project where the file does not exist I would likely consider looking for a way to create the file within my deployment script. A good example of that would be EngineYard’s chef recipe for creating the database.yml file.

  7. Pritesh says:

    cool…I am newbie to RoR and this article made my day , was looking for somthing like this to make the code look simple and flexible… thanks a lot Tim !

  8. Peter Nixey says:

    This is really useful thank you. After looking at this I wondered how you could DRY the config file up and discovered that you can use ‘anchors’ and ‘references’ to do this.
    (http://en.wikipedia.org/wiki/YAML#Language_elements)

    For instance, if the site title is the same in development as test and production then you can define it as follows:

    development:
    site_title: &title My new website

    test:
    site_title: *title

    production
    site_title: *title

    Thanks for the post and hope this is helpful :)

    • Tim Knight says:

      Thanks Peter. Yes you can reference other settings by setting there name with &name. You can see that in use where I’m importing all of the development settings into the test environment. You pointed out however that you can set individual items as well—thanks for digging into more details on the concept.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.