How to elegantly symbolize_keys for a 'nested' hash
There are a few ways to do this
There's a
deep_symbolize_keys
method in Railshash.deep_symbolize_keys!
As mentioned by @chrisgeeq, there is a
deep_transform_keys
method that's available from Rails 4.hash.deep_transform_keys(&:to_sym)
There is also a bang
!
version to replace the existing object.There is another method called
with_indifferent_access
. This allows you to access a hash with either a string or a symbol like howparams
are in the controller. This method doesn't have a bang counterpart.hash = hash.with_indifferent_access
The last one is using
JSON.parse
. I personally don't like this because you're doing 2 transformations - hash to json then json to hash.JSON.parse(JSON[h], symbolize_names: true)
UPDATE:
16/01/19 - add more options and note deprecation of deep_symbolize_keys
19/04/12 - remove deprecated note. only the implementation used in the method is deprecated, not the method itself.
You cannot use this method for params or any other instance of ActionController::Parameters
any more, because deep_symbolize_keys
method is deprecated in Rails 5.0+ due to security reasons and will be removed in Rails 5.1+ as ActionController::Parameters
no longer
inherits from Hash
So this approach by @Uri Agassi seems to be the universal one.
JSON.parse(JSON[h], symbolize_names: true)
However, Rails Hash object still does have it.
So options are:
if you don't use Rails or just don't care:
JSON.parse(JSON[h], symbolize_names: true)
with Rails and ActionController::Parameters:
params.to_unsafe_h.deep_symbolize_keys
with Rails and plain Hash
h.deep_symbolize_keys