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

Ruby on rails 在JBuilder中自动将哈希键转换为camelCase,ruby-on-rails,ruby,jbuilder,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" } }

我使用的是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"
  }
}
但它保留了原始散列键,只将数据对象转换为camelCase

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

所以问题是:使用JBuilder计算散列键的正确方法是什么

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


正如Bryce所提到的,Jbuilder使用json而不是处理散列

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

json.key_format! camelize: :lower

json.data_object do
  @foo.each do |key, value|
    json.set! key, value
  end
end
尽管如此,还是有一个问题:如果@foo为空,它将根本不会创建对象。以下是我找到的解决方案:

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

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

    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?
    
  • 但是,如果必须序列化嵌套对象,则这些解决方案将不起作用。通过对Jbuilder中的
    json
    对象进行MonkeyPatch,可以实现深度序列化

    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!:数据对象@foo
    ,并获得所需的结果。

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

    此gem允许API用户传入并接收camelCased或dash cased键,而Rails应用程序接收并生成snake_cased键

    下面是一篇文章,作者解释了这个宝石背后的想法。


    希望对我有帮助

    我也能得到同样的结果。它不会使散列键骆驼化,嗯,我肯定你做到了,但是你在添加了它之后重新启动了rails服务器,对吗?您还确信jbuilder正在呈现JSON模板,而rails不仅仅是退回到JSON?您可能需要查看如何构建加载到json.array中的哈希数组!是的,我重新启动了它。甚至做了几次,只是为了确定。我不完全确定是否会这样做。如果你能解释一下,我会很高兴的。目前我有一个使用循环的解决方案,如果没有人找到更好的解决方案,我会发布这个解决方案。在我看来,它仍然默认使用to_json进行渲染,并绕过Jbuilder,因此camelize转换没有得到应用。
    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