【问题标题】:Serializing (and deserializing) 'complex' Rails objects with JSON使用 JSON 序列化(和反序列化)“复杂”Rails 对象
【发布时间】:2011-05-09 09:28:25
【问题描述】:

可能是一个愚蠢的问题,但我对 Rails 比较陌生,并且想知道 Rails 如何处理序列化一个模型,该模型具有另一个类的多个(和/或属于_to)对象。它会默认序列化整个对象图吗?你一定想要那个吗?你能控制它吗?如何?

接收端关于如何反序列化的任何技巧?还是蛮力将属性分配给它们的哈希值,然后任何嵌入的数组/哈希都将成为关联的类对象?

编辑:添加使用@zetetic 示例返回的json 示例。想知道为什么嵌入式集合(索环)在每个引号(")之前都有转义(\)字符?

{"name":"Gizmo","height":15,"grommets":"[{\"name\":\"Sid\",\"color\":\"yellow\"},{\"name\":\"Elvis\",\"color\":\"\"},{\"name\":\"Teeny\",\"color\":\"Red\"}

【问题讨论】:

    标签: ruby-on-rails json serialization


    【解决方案1】:

    不,默认情况下,序列化模型实例只会发出它自己的属性,而不是它的关联属性。但是您可以通过在模型中包含 as_json 方法来自定义此行为:

    class MyModel < ActiveRecord::Base
      has_many :widgets
    
      def as_json(options={})
        {
          :name => name,
          :widgets => widgets.to_json
        }
      end
    end
    

    您可能还想在关联模型中定义as_json,否则您将获得属性的标准哈希。

    编辑

    原来上面的例子只适用于顶层,而不适用于最终转义的关联。要使示例正常工作,请在 Widget 中使用所需属性定义 as_json,然后在 MyModel 中对集合的每个元素调用 as_json

    def as_json(options={})
      {
        :name => name,
        :widgets => widgets.map(&:as_json)
      }
    end
    

    我想你可以用 Monkeypatch Array#as_json 代替,不过我更喜欢使用 map

    编辑

    如果您想支持这个答案,请务必先阅读this one。使用:include 是首选方法。

    【讨论】:

    • 谢谢!它大部分都在工作。知道为什么当我添加 as_json(options={}) 并且仅 :name => 命名引用的 :widgets 的每个元素(使用您的示例)时使用反斜杠“转义”(`) characters before each quote("). But this isn't the case for elements in MyModel`。请参阅我之后的示例原始问题。
    • 仅供参考 - 我开始写一篇新文章来回答 反斜杠转义 问题:stackoverflow.com/questions/4348223
    【解决方案2】:

    简单! (在 Rails 2.3.8 上测试)

    来自http://apidock.com/rails/ActiveRecord/Serialization/to_json

    要包含关联,请使用 :include

        konata.to_json(:include => :posts)
      # => {"id": 1, "name": "Konata Izumi", "age": 16,
            "created_at": "2006/08/01", "awesome": true,
            "posts": [{"id": 1, "author_id": 1, "title": "Welcome to the weblog"},
                      {"id": 2, author_id: 1, "title": "So I was thinking"}]}
    

    有关更多信息,请参阅上面的链接。

    对我来说,它甚至可以与 ":has_many, :through" 关联一起使用。

    【讨论】:

    • 任何人都可以验证这是与 Rails 3 一起使用的首选方法(或至少有效)吗? Rails 3 缺少您链接到的文档...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多