繁体   English   中英

用所有关系跟踪to_json

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM