2010-11-13 75 views
1

可能是一个愚蠢的问题,对象,但我是比较新的Rails和想知道如何Rails的句柄序列化的has_many(和/或belongs_to的)另一个类的对象的模型。它会默认序列化整个对象图吗?你是否一定要这么做?你能控制它吗?怎么样?序列化(和反序列化)“复杂”与Rails的JSON

上关于如何反序列化接收端什么花样?或者非常蛮力的属性分配给它们的散列值,并且任何嵌入的数组/散列会成为关联的类对象?

编辑:添加使用@ zetetic示例返回的json示例。想知道为什么嵌入式收集(垫圈)在每次报价(")之前都有逃脱(\)的字符?

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

回答

3

不,默认情况下,序列化模型实例只会发出自己的属性,而不会发出与其关联的属性。但是你可以通过在模型中的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 

我猜你会猴补丁阵列#as_json代替,但我更喜欢使用map

编辑

如果你正在考虑upvoting这个答案的,请务必阅读this one第一。使用:include是首选方法。

+0

谢谢!它*主要*工作。任何想法为什么当我添加'as_json(options = {})'并且只有:name =>为每个元素引用':widgets'(使用你的例子)时,每个元素之前都带有反斜杠('\') quote(''')。但是这不适用于'MyModel'中的元素。请参阅原始问题后的示例。 – Meltemi 2010-12-03 07:36:40

+0

仅供参考 - 我开始了一个新帖子以获得**反斜杠转义**问题的答案: ?http://stackoverflow.com/questions/4348223 – Meltemi 2010-12-03 18:40:12

1

简单! (on Rails的2.3.8测试)

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

要包括的关联,使用:包括

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,:通过” 协会。

+0

任何人都可以验证这是首选的方法(或至少作品)与Rails 3的链接到该文档中缺少为Rails 3 ... – Meltemi 2010-12-30 18:45:17

+0

的http:// api.rubyonrails。组织/班/加载ActiveModel /串行器/ JSON.html – Duke 2012-10-04 02:45:01