【问题标题】:Rails to_json with all relationsRails to_json 与所有关系
【发布时间】:2013-10-26 12:48:03
【问题描述】:

我有一个 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

【问题讨论】:

  • 你知道 rabl gem 吗?我认为你可以使用它。 github.com/nesquena/rabl
  • 项目类也包含许多项目?
  • @shiva 是的。所以基本上对于每个项目我都能做到 Item.first.items
  • 你能把select * from item的结果贴出来

标签: ruby-on-rails ruby json activerecord has-many


【解决方案1】:

不建议覆盖 as_json 或 to_json

原因是您需要其他地方的原始数据,并且您可能需要其他格式的数据。 Manipulate 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

【讨论】:

  • 覆盖as_json 我这样做的方式只是更改了默认值,因此您始终可以通过传入参数to to_json 回到以前的行为。无论如何,使用序列化器更好(我使用 as_json 因为这是官方推荐的方法),所以你是对的:)
【解决方案2】:

首先,我建议使用像 ancestryawesome nested set 这样的 gem。它将帮助您有效地管理您的项目树结构(在一个 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

【讨论】:

  • 这似乎不起作用(或者我需要先安装 gems 吗?)这实际上是我的应用程序中唯一的这种情况,我不需要很多选项,但我会有看看这些宝石是否让生活更轻松。谢谢!
  • 对不起,没有测试。什么不起作用?第一个还是第二个解决方案?
  • 哎呀,错字了。 includes => ìnclude
  • 顺便说一句,gem 是可选的。这只是一种更有效地在数据库中存储和管理树结构的方法(因为我们使用递归,我们可能有很多后续查询:每个叶节点一个!)
猜你喜欢
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-01
  • 1970-01-01
相关资源
最近更新 更多