在JBuilder中自动将哈希键转换为camelCase

时间:2016-06-01 12:59:46

标签: ruby-on-rails ruby jbuilder

我正在使用JBuilder版本2.4.1和Rails 4.2.6。我正在尝试将复杂对象序列化为JSON。代码如下:

json.key_format! camelize: :lower

json.data_object @foo

@foo看起来像这样:

{
  key: 'value',
  long_key: 'value'
}

我希望它呈现为

{
  "dataObject": {
    "key": "value",
    "longKey": "value"
  }
}

但它保留了原始的哈希键,只将data_object转换为camelCase

{
  "dataObject": {
    "key": "value",
    "long_key": "value"
  }
}

所以问题是:使用JBuilder对哈希密钥进行渲染的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

尝试在应用程序中全局设置(例如config / environment.rb)

Jbuilder.key_format camelize: :lower

答案 1 :(得分:2)

正如Bryce所说,Jbuilder使用to_json而不是处理哈希。

一个简单的解决方案是使用json.set!手动序列化哈希。

json.key_format! camelize: :lower

json.data_object do
  @foo.each do |key, value|
    json.set! key, value
  end
end

虽然存在一个问题:如果@foo为空,则根本不会创建对象。这些是我找到的解决方案:

  1. 在序列化之前定义一个空哈希

    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
    
  2. 如果源变量为空,则序列化空哈希

    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
    

    或者如果您更喜欢代码平面

    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?
    
  3. 但是,如果必须序列化嵌套对象,那么这些解决方案将无效。您可以通过monkeypatching Jbuilder中的json对象

    来实现深度序列化
    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
    

    然后您可以简单地使用json.hash! :data_object, @foo并获得所需的结果。

答案 2 :(得分:1)

我不确定这是否仍然相关。但对于那些仍在寻找优雅解决方案的人,我建议你看看:

https://github.com/vigetlabs/olive_branch

  

这个gem允许你的API用户传入并接收camelCased或dash-cased键,而你的Rails应用程序接收并生成基于snake_的键。

这是一篇帖子,作者解释了这个宝石背后的想法。 https://www.viget.com/articles/introducing-olivebranch/

希望有所帮助