Always double check symbol vs string keys in hash objects

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the ruby category.

Last Updated: 2024-11-23

I had something like the following to store my config for a Redis DB instance:

test:
  url: redis://localhost:6379
  db: 2
development:
  url: redis://localhost:6379
  db: 3

This config was consumed with this code:

config_file = Rails.root.join('config', 'redis.yml')
config = YAML.safe_load(ERB.new(config_file.read).result)[Rails.env] || {}

Redis.current = Redis.new(url: config[:url], db: config[:db])

The issue was that, despite the symbol like presentation of the yaml keys in the yaml file, it was in fact parsed as strings by Ruby. Therefore my reference of config[:url] contained nil and my redis connection failed.

Here is the fix:

config_file = Rails.root.join('config', 'redis.yml')
Redis.current = Redis.new(url: config["url"], db: config["db"])

Lesson

Always check whether some hash or hash-like object actually contains symbols or strings -- especially if it is generated.