Rails - 使用 camelize 将模型序列化为 JSON

Posted

技术标签:

【中文标题】Rails - 使用 camelize 将模型序列化为 JSON【英文标题】:Rails - Serialize Model to JSON with camelize 【发布时间】:2011-09-06 17:38:00 【问题描述】:

我需要将模型序列化为 json 并将所有键都骆驼化。我看到 to_xml 中有一个选项可以允许驼峰式大小写。我似乎无法强迫 json 序列化给我一个骆驼散列。这在 Rails 中是可能的吗?

【问题讨论】:

根据 Bert 的建议,我们选择了 RABL。再高兴不过了,这里有一个使用 RABL 的教程:blog.dcxn.com/2011/06/22/rails-json-templates-through-rabl 你是如何让 rabl 返回骆驼化 json 的? 【参考方案1】:

我遇到了类似的问题。经过一番研究,我将as_json ActiveModel 方法与一个可以骆驼化哈希键的帮助程序包装起来。然后我会将模块包含在相关模型中:

# lib/camel_json.rb
module CamelJson
  def as_json(options)
    camelize_keys(super(options))
  end

  private
  def camelize_keys(hash)
    values = hash.map do |key, value|
      [key.camelize(:lower), value]
    end
    Hash[values]
  end
end



# app/models/post.rb
require 'camel_json'
class Post < ActiveRecord::Base
    include CamelJson
end

这对于我们相对简单的情况非常有效。但是,如果您使用的是 JBuilder,显然有一个配置可以将驼峰大小写设置为默认值:https://***.com/a/23803997/251500

【讨论】:

出于纯粹的科学原因,我使用了这段代码,但不得不对其进行修改以检查键和值是否不为零。把它放在values = hash.map do |key, value| 小改动,只是想我会提到它。 请注意,此实现不会转换嵌套哈希的键。例如,user.as_json(only: [:first_name], include: :mailing_address) 将离开 zip_codesnake-cased: "firstName" =&gt; "Alan", "mailingAddress" =&gt; "id": 1, "zip_code" =&gt; "10004"【参考方案2】:

如果您使用的是 rails,请跳过添加的依赖项并使用 Hash#deep_transform_keys。它还具有骆驼化 nested keys 的额外好处(如果您正在执行类似user.as_json(includes: :my_associated_model) 的操作,则非常方便):

h = "first_name" => "Rob", "mailing_address" => "zip_code" => "10004"
h.deep_transform_keys  |k| k.camelize(:lower) 
=> "firstName"=>"Rob", "mailingAddress"=>"zipCode"=>"10004"

来源:https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/core_ext/hash/keys.rb#L88

【讨论】:

【参考方案3】:

在 Rails 中使用驼峰化的属性名称对我来说似乎很奇怪,更不用说 json。我会遵守约定并使用带下划线的变量名。

但是,看看这个宝石:RABL。应该能帮到你。

【讨论】:

伯特-你在球上。也感谢您查看这个问题。我正在尝试让 rails json api 对另一端的 javascript 开发人员尽可能干净。 RABL 看起来可以为我节省大量时间!谢谢! javascript 按照惯例使用驼峰大小写,json 属性也改为驼峰化不是更有意义吗? 提示:如果您使用类似ngResource 的东西不喜欢来自RABL 的json-api 样式响应,请尝试将object @thing =&gt; false 用于对象,将:object_root =&gt; false 用于子对象和集合 【参考方案4】:

直接使用 RABL 渲染器,您可以传递一个内联模板,而不是从文件中获取它:

Rabl::Renderer.new("\nattributes :name, :description", object).render

\n 字符必须在字符串的开头。

【讨论】:

【参考方案5】:

就我而言,我需要自定义一些键名。

用法

puts self.camelize_array(array:Post.all.to_a,conditions:id: "_id",post_type: "type")

实施

def self.camelize_array(array:,conditions: )
    final = JSON.parse array.to_json
    final.each do |a|
        a.transform_keys! do |key| 
            if conditions.keys.include? key.to_sym
                key = conditions[key.to_sym]
            else
                key.camelize(:lower)
            end
        end
    end
    final.to_json
end

【讨论】:

以上是关于Rails - 使用 camelize 将模型序列化为 JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot 中为 Camel 配置 Jackson ObjectMapper

在 Rails JSON 序列化中重命名模型关联属性?

Akka 是不是淘汰了 Camel?

python 如何使用camel序列化对象。来自https://eev.ee/blog/2015/10/15/dont-use-pickle-use-camel/

Camel Restlet异步发送对客户端的响应

使用 postgresql 和 ruby​​ on rails 优化时间序列数据检索的数据库查询