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

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

【问题讨论】:

标签: ruby-on-rails json serialization activerecord


【解决方案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://stackoverflow.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
      

      【讨论】:

        猜你喜欢
        • 2017-03-03
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        • 2020-09-29
        • 1970-01-01
        相关资源
        最近更新 更多