-
Notifications
You must be signed in to change notification settings - Fork 440
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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" }}
- Loading branch information
Showing
3 changed files
with
196 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters