我遇到了一个我正在使用as_json方法的问题,以及如何在JSON 中有效地返回对象和它的belongs_to对象也是JSON,其中belongs_to对象具有它自己的belongs_to对象。代码可能会更好地解释它。
不工作方式
警报类
class Alert < ActiveRecord::Base
belongs_to :message
# for json rendering
def as_json(options={})
super(:include => :message)
end
end
消息类
def as_json(options={})
super( methods: [:timestamp, :num_photos, :first_photo_url, :tag_names],
include: { camera: { only: [:id, :name] },
position: { only: [:id, :name, :address, :default_threat_level ]},
images: { only: [:id, :photo_url, :is_hidden]} })
end
第一次设置的问题是当我有一个Alert对象并调用
时alert.as_json()
我从Alert中获取了所有属性,并从Message中获取了所有属性,但是没有来自Message的其他属性,如Camera,Position等。
这是“它正在工作,但可能不是正确的设计方式”
警报类
class Alert < ActiveRecord::Base
belongs_to :message
# for json rendering
def as_json(options={})
super().merge(:message => message.as_json)
end
end
消息类
# for json rendering
def as_json(options={})
super( methods: [:timestamp, :num_photos, :first_photo_url, :tag_names])
.merge(:camera => camera.as_json)
.merge(:position => position.as_json)
.merge(:images => images.as_json)
end
在第二个设置中,我得到了所有Message的嵌套属性,就像我想要的那样。
我的问题是,我是否错过了一些适当的Rails公约?似乎会有/应该是一种更容易的方式。
答案 0 :(得分:7)
对我来说最好的答案是使用serializable_hash
。 @kikito在他的评论中提到了这一点,但有一个错字阻止它工作。它不是serialized_hash
,而是serializable_hash
。
直接找到+ as_json
替换serializable_hash
,这个错误消失了。 (它仍未在今天的Rails 4.0.2中修复)。您还可以获得以后更轻松地实现XML API的好处(有些人仍然使用它们!)。
答案 1 :(得分:3)
您使用的是哪个版本的Rails?这是旧版Rails中的一个已知错误,据称已使用this pull request修复。你的语法看起来对我来说,也许这是你的问题?
顺便说一句,您可能还想从Jose Valim(Rails核心成员)签出新的active_model_serializers。它可能至少使您能够以更优雅的方式解决您的问题。
答案 2 :(得分:1)