如果每个嵌套资源也可以在其下嵌套资源,如何在rails中将嵌套资源呈现为json?

时间:2016-11-06 18:39:55

标签: ruby-on-rails ruby

所以在我的rails应用程序中有列表。每个List has_one Item。每个项目都有很多项目。所以Item可以属于另一个Item。我想将这些资源渲染为JSON,其中每个Item都有其子项嵌套在其下。由于每个Item可能都有自己的子项,因此我不能继续使用include:选项,因为我不知道最后一个Item何时没有子项。

所以看起来我在渲染JSON时必须以某种方式使用递归,所以如果一个Item有子节点,它的子节点嵌套在它下面,如果这些子节点中有任何一个有子节点,它们的子节点就嵌套在它们之下。

我不知道如何使用to_json和include选项来完成此操作。如果我只是渲染列表的第一个子项,我会这样做:

  respond_to do |format|
    format.json { render json: @list.to_json(include: :item) }
  end

但我不知道如何以递归方式呈现:item及其子项的Item子项,依此类推。

另一个答案建议使用视图对象或像RABL这样的宝石来解决另一个对于to_json而言似乎过于复杂的问题。我正在尝试为to_json方法做太复杂的事情?递归渲染子资源为json的最佳选择是什么?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

如果您可以使用自定义方法来准备json,那么您可以这样做:

class List
  has_one :item

  def custom_json
    json = to_json
    json[:item] = item.custom_json
    json
  end
end

class Item
  has_many :items # add other options

  def custom_json
    json = to_json.merge(children: [])
    items.each { |item| json[:children] << item.custom_json }
    json
  end
end

注意:此处items指的是Item类中其子项的关系。

在你的控制器中,你可以做到

format.json { render json: @list.custom_json }

这将导致json结构:

{ list_attr: value, list_attr_2: value, item: { item_attr: value, children: [{ child_item_attr: value, ... }] } }

如果有帮助,请告诉我。