You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve key formatting for nested hashes and disable by default (#497)
* Fix changing key format in child elements
Since #486, key format is applied deeply to hashes and arrays that are
passed to `set!`, `merge!` and `array!`:
json.key_format! :upcase
json.set!(:foo, {some: "value"})
# => {"FOO": {"SOME": "value"}}
json.key_format! :upcase
json.merge!({some: "value"})
# => {"SOME": "value"}
json.key_format! :upcase
json.array!([{some: "value"}])
# => [{"SOME": "value"}]
This also works for arrays and hashes extracted from objects:
comment = Struct.new(:author).new({ first_name: 'John', last_name: 'Doe' })
json.key_format! camlize: :lower
json.set!(:comment, comment, :author)
# => {"comment": {"author": {"firstName": "John", "lastName": "Doe"}}}
As a side effect of the change, key format is also applied to the
result of nested blocks, making it impossible to change key format in
the scope of a block:
json.key_format! camelize: :lower
json.level_one do
json.key_format! :upcase
json.value 'two'
end
# => jbuilder 2.10.0: {"levelOne": {"VALUE": "two"}}
# => jbuilder 2.11.0: {"levelOne": {"vALUE": "two"}}
The string "vALUE" results from calling
`"value".upcase.camelize(:lower)`. The same happens when trying to
change the key format inside of an `array!` block.
This happens since key transformation was added in the `_merge_values`
method, which is used both by `merge!` but also when `set!` is called
with a block.
To restore the previous behavior, we pull the `_transform_keys` call
up into `merge!` itself. To make sure extracted hashes and arrays keep
being transformed (see comment/author example above), we apply
`_transform_keys` in `_extract_hash_values` and
`_extract_method_values`.
This also aligns the behavior of `extract!` which was left out in #486:
comment = {author: { first_name: 'John', last_name: 'Doe' }}
result = jbuild do |json|
json.key_format! camelize: :lower
json.extract! comment, :author
end
# => jbuilder 2.10 and 2.11: {"author": { :first_name => "John", :last_name => "Doe" }}
# => now: {"author": { "firstName": "John", "lastName": "Doe" }}
Finally, to fix `array!`, we make it call `_merge_values` directly
instead of relying on `merge!`. `array!` then has to transform keys
itself when a collection is passed to preserve the new behavior
introduced by #486.
* Disable deeply formatting keys of nested hashes by default
Since #486, key format was also applied to nested hashes that are
passed as values:
json.key_format! camelize: :lower
json.settings({some_value: "abc"})
# => { "settings": { "someValue": "abc" }}
This breaks code that relied on the previous behavior. Add a
`deep_format_keys!` directive that can be used to opt into this new
behavior:
json.key_format! camelize: :lower
json.deep_format_keys!
json.settings({some_value: "abc"})
# => { "settings": { "someValue": "abc" }}
0 commit comments