首页 > 解决方案 > 如何使用嵌套的 json 对象创建 json 响应?

问题描述

我正在用 ruby​​ on rails 创建一个 api,我有几个表事件、艺术家和国家,事件有艺术家 ID,它是艺术家中 id 字段的外键。事件也有 country_id,它是国家 ID 字段的外键。当用户向我的 api 询问 /events/artist/:artist_id 时,我想以以下形式返回 json 结果

[
{
    "id":1,
    "type":"festival",
    "artist":{
      "id":1,
      "name":"doesnt matter"
    },
    "country":{
      "id":1,
      "name":"cambodia"
    }
]

但是我不确定如何在我的 json 响应中包含嵌套对象,我是否会进行多个查询以及如何将它们注入到我的 json 响应中?我相信还有更好的方法来为此设置我的数据库,我愿意接受建议,但是一个活动只能有一个艺术家并且在一个国家,尽管国家可以有多个活动。我的问题的核心不是数据库,但我找不到任何信息如何在我的响应中嵌套查询。(这是我认为我需要做的) ruby on rails - 6.0.2,ruby 2.7.1

标签: ruby-on-railsjsonactiverecord

解决方案


您可以as_json在您的活动中使用方法。

它是完全可定制的:

@artist = Artist.find(params[:artist_id])

@artist.events.as_json(
  only: [:id, :type],
  include: [
    artist: {only: [:id, :name]},
    country: {only: [:id, :name]}
  ]
)

但是,这将为每个事件生成一个查询Event.all加上两个查询。要预加载所有艺术家和国家/地区并仅执行 3 个查询,您可以执行以下操作:

@artist.events.includes([:artist, :country]).as_json(
  only: [:id, :type],
  include: [
    artist: {only: [:id, :name]},
    country: {only: [:id, :name]}
  ]
)

除此之外,如果艺术家始终相同,则不应为每个事件返回艺术家 json。(因为您搜索了与同一艺术家相关的事件)。你会得到无用的数据重复。您可以尝试以其他方式格式化您的数据:

@artist.as_json(
  only: [:id, :name],
  include: [
    events: {
      only: [:id, :name],
      include: {
        country: {only: [:id, :name]}
      }
    }
  ]
)

推荐阅读