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_code
snake-cased: "firstName" => "Alan", "mailingAddress" => "id": 1, "zip_code" => "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 => false
用于对象,将:object_root => 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
python 如何使用camel序列化对象。来自https://eev.ee/blog/2015/10/15/dont-use-pickle-use-camel/