嵌套资源as_json,已排序,具有特定列

时间:2018-02-19 22:37:31

标签: ruby-on-rails ruby

我有3个资源:pagessectionsfields,每个资源都有nameorder列。

我的目标是获取所有这些资源的JSON表示,按其订单列排序。

示例输出:

[
  {"name": "Page 1", "order": 0, "sections":  [
    {"name": "Section 1", "order": 0, "fields": [
      {"name": "Field 1", "order": 0},
      {"name": "Field 2", "order": 1}
    ]},
    {"name": "Section 2", "order": 0, "fields": [
      {"name": "Field 1", "order": 0}
    ]}
  ]},
  {"name": "Page 2", "order": 1, "sections": [
    {"name": "Section 1", "order": 0, "fields": [
      {"name": "Field 1", "order": 0}
    ]}
  ]}
]

请注意,上面是实际的JSON(即在运行to_json之后)。

对于我的生活,我无法想出用ActiveModel做到这一点的方法。

我最成功的尝试是这样的:

Page.joins(sections: :fields)
  .as_json(only: [:name, :order], include: {
    sections: {only: [:name, :order], include: {
      fields: {only: [:prototype_id, :order]}
    }}
  })

这允许我选择名称和顺序,但是我必须递归地对每个数组进行排序。

如果我尝试让ActiveModel进行排序,我必须选择SQL中的特定列,这需要我加入,这需要一个独特的,这使得JSON嵌套非常棘手......

有谁可以指出我在这里做错了什么?

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

在AR上实施订单有两种解决方案:

解决方案#1:
您可以使用 .order 订购模型及其关联,如下所示:

Page.joins(sections: :fields).order("pages.order, sections.order, fields.order")

<强>参考:
https://apidock.com/rails/ActiveRecord/QueryMethods/order

解决方案#2:
将排序添加到默认范围,如下所示:

class Page 
  default_scope { order(order: :asc) }
end

class Section 
  default_scope { order(order: :asc) }
end

class Field 
  default_scope { order(order: :asc) }
end

<强>参考:
https://apidock.com/rails/ActiveRecord/Base/default_scope/class