How to Access a Hash with both String and Symbol Keys in Rails

Sometimes, you receive a hash key as a method parameter or via user input, and you want to make your hash understand that key as-is, without worrying if it's a string or a symbol. A good example is the params
hash in Rails. You can access it using either a string or a symbol.
If you try to access a regular Ruby hash with a non-existent key, it returns nil
value.
ak = {
name: 'Akshay',
age: 30
}
ak[:name] # "Akshay"
ak['name'] # nil
Rails provides the ActiveSupport::HashWithIndifferentAccess
class which implements a hash where keys :foo
and "foo"
are considered to be the same.
h = ActiveSupport::HashWithIndifferentAccess.new
h[:name] = 'akshay'
h[:name] # "akshay"
h['name'] # "akshay"
If that long class name looks intimidating, don't worry, you don't have to initialize this class yourself. Instead, use the with_indifferent_access
extension method.
ak = {
name: 'Akshay',
age: 30
}
h = ak.with_indifferent_access
h[:name] # "Akshay"
h['name'] # "Akshay"
The with_indifferent_access
method is added by Active Support by monkey-patching the Hash class.
# lib/active_support/core_ext/hash/indifferent_access.rb
class Hash
def with_indifferent_access
ActiveSupport::HashWithIndifferentAccess.new(self)
end
end
As seen above, this method returns a new instance of the ActiveSupport::HashWithIndifferentAccess
class, initializing it with the current hash. This class supports all the existing hash API, so you can call any method you'd call on a regular Ruby hash.