Dynamically load configuration tokens using Ruby’s metaprogramming magic

This was originally posted by me on Coderwall.

So, let’s say you need to use tokens in your app to access a third-party API (like Twitter, Instagram, or Facebook). In Ruby gems tutorials it’s very common to see the following example code to load these tokens:

module Facebook
  CONFIG = YAML.load_file(Rails.root.join("config/facebook.yml"))[Rails.env]
  APP_ID = CONFIG['app_id']
  SECRET = CONFIG['secret_key']
end

This was extracted from the Koala’s gem wiki on GitHub. Or the following one, which was extracted from the README.md file of the Instagram gem GitHub repo.

Instagram.configure do |config|
  config.client_id = "YOUR_CLIENT_ID"
  config.client_secret = "YOUR_CLIENT_SECRET"
end

It’s a very ugly practice to hardcode things like this, IMHO.

Now, the most recommended and used practice in the wild is to have these API access tokens in a YAML file, so they can be loaded into our app, like the Koala’s example code from above. The format is the one that follows:

...
twitter:
  consumer_key: YOUR_CONSUMER_KEY
  consumer_secret: YOUR_CONSUMER_SECRET
  oauth_token: YOUR_OAUTH_TOKEN
  oauth_token_secret: YOUR_OAUTH_TOKEN_SECRET
...

As you may know, this file is loaded as a Hash. So we can access each key and value.

Now, using Ruby’s metaprogramming magic we can load each key of the file and use it in the configuration section of the gem. How? Using the .send() method.

CONFIG = YAML.load_file(Rails.root.join("config", "settings.yml"))[Rails.env]

Twitter.configure do |twitter|
  CONFIG['twitter'].each_key do |key|
    twitter.send("#{key}=", CONFIG['twitter'][key])
  end
end

The secret is to name each key in the YAML file section exactly as the name of the configuration key of the gem, so there won’t be any method_missing error.

You can find more information about the .send() method on the Ruby Documentation page.

 
13
Kudos
 
13
Kudos

Now read this

My Manager’s README

Photo by Ian Schneider on Unsplash Inspired by Edgar’s fantastic post and other Engineering Managers, I’m following the same principle to outline my views for existing and new team contributors. Effective onboarding is crucial to our... Continue →