[英]Rails to_json with all relations
我有一个Item类,其中也包含许多项目(使用has_many)。 我想做的是阅读没有父项的所有项(顶层)及其所有子项。 所以基本上我需要将整个Item表正确嵌套到json中。
这是我现在正在使用的代码,但这只返回顶级项目及其项目,没有比这更低的代码了。 (所以我只剩下两个级别)
@items = Item.where("item_id IS ?" , nil).order("position")
respond_to do |format|
format.json { render :json => @items.to_json(:include => :items)}
end
我不建议覆盖as_json或to_json 。
原因是您将在其他地方需要原始数据,并且可能需要其他格式的数据。 操纵as_json
将最终更改数据,并且您无法扩展。
使用装饰器是必经之路。 一个不错的选择是ActiveModel Serializers 。 基本上是这样的
class ItemSerializer < ActiveModel::Serializer
attributes :id, :title, :body
has_many :comments # The JSON output will have comments inside.
end
然后在您的控制器中:
@items = Item.where("item_id IS ?" , nil).order("position")
respond_to do |format|
format.json { render :json => @items }
end
您的@items
将由ItemSerializer自动序列化。
或者您可以选择自定义序列化程序
render json: @items, each_serializer: ItemWithAssociatedSerializer
首先,我建议您使用祖先之类的宝石或令人敬畏的嵌套套件 。 它将帮助您有效地管理Items树结构(在一个SQL查询中检索整个层次结构,依此类推)。
然后您可以执行以下操作:
class Item
def as_json(options={})
super({include: items}.merge options)
end
end
这意味着在默认情况下,在项目上调用to_json
会包含子项的json; 因此,我们递归地遍历整个层次结构。
如果您需要一种方法来限制嵌套级别的数量,则可以执行以下操作:
class Item
def as_json(options={})
return super({include: items}.merge options) unless options[:depth].present?
if options[:depth] > 0
super({include: items, depth: options[:depth] - 1}.merge options)
else
super
end
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.