检索深度嵌套的 ActiveRecord 关联

Retrieving deeply nested ActiveRecord associations

我无法弄清楚如何检索具有深层嵌套关联的 ActiveRecord 对象。下面是我试图实现的一个示例,表示为 JSON 对象。

目前,我的项目模型有:

  1. has_many :groups
  2. has_many :users, through: :groups
  3. has_many :members, through: :groups, source: :users

预期结果(JSON):

{
  "id": 7,
  "name": "Test Project",
  "description": "Project description",
  "groups": [
    {
      "id": 1,
      "name": "Test Group 1",
      "description": "First test group",
      "members": [
        {
          "id": 1,
          "name": "Admin",
          "email": "admin@exmaple.com"
        },
        {
          "id": 2,
          "name": "Test User",
          "email": "test@exmaple.com"
        }
      ]
    }
  ]
}

示例代码:

class Project < ActiveRecord::Base
  has_many :groups
  has_many :users, through: :groups
  has_many :members, through: :groups, source: :users
end

我最接近预期结果的方法是向项目模型添加组方法以获取所有成员:

最接近的结果(JSON):

{
  "id": 7,
  "name": "Test Project",
  "description": "Project description",
  "groups": [
    {
      "id": 1,
      "name": "Admin",
      "email": "admin@exmaple.com"
    },
    {
      "id": 2,
      "name": "Test User",
      "email": "test@exmaple.com"
    }
  ]
}

示例代码:

class Project < ActiveRecord::Base
  has_many :groups
  has_many :users, through: :groups
  has_many :members, through: :groups, source: :users

  def groups
    members.all
  end
end

您可以尝试使用 activemodel 序列化程序来包含关联记录。

class ProjectSerializer < ActiveModel::Serializer
  attributes :id
  has_many :groups 
end

class GroupSerializer < ActiveModel::Serializer
  attributes :id
  has_many :members
end

您可以在以下位置查看:https://github.com/rails-api/active_model_serializers

The has_many, has_one, and belongs_to declarations describe relationships between resources. By default, when you serialize a Post, you will get its Comments as well.

你可以这样做:

class Project < ActiveRecord::Base
  has_many :groups
  has_many :users, through: :groups
  has_many :members, through: :groups, source: :users
end

Project.find(7).to_json(include: {groups: {include: :users}})