I am using JBuilder version 2.4.1 and Rails 4.2.6. I am trying to serialize a complex object to JSON. The code looks as follows:
json.key_format! camelize: :lower
json.data_object @foo
@foo
looks like this:
{
key: 'value',
long_key: 'value'
}
I expect it to be rendered as
{
"dataObject": {
"key": "value",
"longKey": "value"
}
}
But instead it keeps the original hash keys, only converting data_object into camelCase
{
"dataObject": {
"key": "value",
"long_key": "value"
}
}
So the question is: what is the proper way to camelize hash keys using JBuilder?
As Bryce has mentioned, Jbuilder uses to_json instead of processing the hash.
A simple solution is to use json.set!
to manually serialize the hash.
json.key_format! camelize: :lower
json.data_object do
@foo.each do |key, value|
json.set! key, value
end
end
Although, there is an issue: if @foo is empty, it won't create an object at all. These are the solutions I found:
Define an empty hash before the serialization
json.key_format! camelize: :lower
json.data_object({}) # don't forget parentheses or Ruby will handle {} as a block
json.data_object do
@foo.each do |key, value|
json.set! key, value
end
end
Serialize an empty hash if the source variable is empty
json.key_format! camelize: :lower
if (@foo.empty?) do
json.data_object({})
else
json.data_object do
@foo.each do |key, value|
json.set! key, value
end
end
end
Or if you prefer your code flat
json.key_format! camelize: :lower
json.data_object({}) if @foo.empty?
json.data_object do
@foo.each do |key, value|
json.set! key, value
end
end unless @foo.empty?
However, those solutions will not work if you have to serialize nested objects. You can achieve deep serialization by monkeypatching the json
object inside Jbuilder
def json.hash!(name, hash)
if hash.empty?
set! name, {}
else
set! name do
hash.each do |key, value|
if value.is_a?(Hash)
hash! key, value
else
set! key, value
end
end
end
end
end
Then you can simply use json.hash! :data_object, @foo
and get the desired result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With