umezo
umezo

Reputation: 1579

YAML configuration file: Why 'example' instead of :example?

I set up an environment YAML file for environment specific variables like username and password. To use these variables in my app, I need to use APP_CONFIG['username'] instead of APP_CONFIG[:username]. Why is this? How would I enable the latter instead? Not a major issue, but it bothers me to not know the cause of the difference.

config/initializers/load_app_config.rb

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

config/app_config.yml

development:
  username: development_name
  password: secret

production:
  username: production_name
  password: super_secret

Upvotes: 3

Views: 4049

Answers (2)

Simone Carletti
Simone Carletti

Reputation: 176402

By default, a YAML key is rendered as String.

development:
  username: development_name
  password: secret

is accessible by

APP_CONFIG = YAML.load_file("#{Rails.root}/config/app_config.yml")[Rails.env]
APP_CONFIG['development']['username']
# => "development_name"

I you want a specific key to be a symbol, you should prefix it with : in the YAML file.

development:
  :username: development_name
  :password: secret

APP_CONFIG = YAML.load_file("#{Rails.root}/config/app_config.yml")[Rails.env]
APP_CONFIG['development'][:username]
# => "development_name"
APP_CONFIG['development']['username']
# => nil

Normally, this is not done because this is a specific Ruby behavior. Other languages might not be happy about the leading :.

If you specifically wants to access keys as symbol, you can either use symbolize_keys!

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

but most of the time, the effort is not worth. Internally, the 90% of libraries converts Symbols to Strings during a comparison, especially when you deal with hashes with indifferent access. So, at the end of the story, you might want to keep strings in this case.

Last option would be to create a HashWithIndifferentAccess

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

This will allow you to access

APP_CONFIG[:development][:username]
APP_CONFIG['development'][:username]
APP_CONFIG['development']['username']

indifferently. It works by storing the hash keys to string internally and converting the request to [] to string, so that it always works. This is the class used by several Rails components, including the famous params[] hash in the controllers.

Upvotes: 9

rmk
rmk

Reputation: 4455

Use symbolize_keys on the hash returned by YAML.load_file

Upvotes: 2

Related Questions