The DeepHashTransformer
helps to translate keys in deeply nested hash (and array) structures.
In opposite to the ActiveSupport's deep_transform_keys
method deep_transform_keys
is the DeepHashTransformer
able to transform keys in hashes that are stored in nested arrays, for example a structure like this { foo: [{ bar: 1 }, { bar: 2 }] }
A good use-case might be the transformation of a JSON API style hash (dasherized string keys) that was returned by an API to a hash that follows common Ruby idioms (symbolized underscore keys), see Complex Example below.
Include the gem in your Gemfile:
gem 'deep_hash_transformer'
When you are still on Ruby 2.2 – 2.4:
gem 'deep_hash_transformer', '~> 1.0.0'
When you are still on Ruby 2.1 or below:
gem 'deep_hash_transformer', '~> 0.1.1'
And then execute:
$ bundle
Or install it yourself as:
$ gem install deep_hash_transformer
The latest version of the DeepHashTransformer
has the following key transformation operations implemented:
:camel_case
- translates keys into
CamelCase
, example:"foo_bar" => "FooBar"
:dasherize
- translates underscores in keys into dashes, example: "foo_bar" => "foo-bar"
:identity
- returns the keys unchanged
:pascal_case
- translates keys into
pascalCase
, example:"foo_bar" => "fooBar"
:snake_case
- translates keys into
snake_case
, example:"FooBar" => "foo_bar"
:stringify
- translates symbol keys into strings, example
:fooBar => "fooBar"
:symbolize
- translates string keys into symbols, example
"fooBar" => :fooBar
:underscore
- translates dashes in keys into underscores, example:
:foo-bar => "foo_bar"
:compact
- removes
nil
values from the hash, example:{ a: 1, b: nil } => { a: 1 }
:compact_blank
- removes blank values (
nil
,false
, or empty values) from the hash, example:{ a: 1, b: '' } => { a: 1 }
All transformations can be called by their names, for example:
DeepHashTransformer.new({ foo_bar: 'baz' }).dasherize
#=> { 'foo-bar' => 'baz' }
Or you can use tr
to chain multiple transformations:
DeepHashTransformer.new({ 'foo-bar' => 'baz' }).tr(:underscore, :symbolize)
#=> { foo_bar: 'baz' }
It is worth noting that the DeepHashTransformer
only transforms string or symbol keys and leaves all other types untouched:
DeepHashTransformer.new({ 1 => 'foo', :bar => 'bar', Object => 'baz' }).stringify
#=> { 1 => 'foo', 'bar' => 'bar', Object => 'baz' }
All transformations apart from symbolize
return per default hashes with stringify keys. When you want to have symbolized keys to be returned, then use tr
to chain your required transformation with :symbolize
DeepHashTransformer
transforms all hash keys – even if the key is nested in another hash or stored in a nested array. This is its biggest advantage over ActiveSupport's deep_transform_keys
method, which is not able to handle hashes in nested arrays.
Example: Transformation of a JSON API style hash (dasherized string keys) to a hash that follows common Ruby idioms (symbolized underscore keys).
json_api_style = {
'nested-array' => [
{ 'a-key' => 'a-value', 'b-key' => nil }
],
'foo_bar' => 'baz'
}
DeepHashTransformer.new(json_api_style).tr(:underscore, :symbolize, :compact)
#=> {
# nested_array: [
# { a_key: 'a-value' }
# ],
# foo_bar: 'baz'
# }
Bug reports and pull requests are welcome on GitHub at https://github.com/spickermann/deep_hash_transformer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new pull request.
The gem is available as open source under the terms of the MIT License.