OBCENEIKON
OBCENEIKON

Reputation: 387

Retrieving deeply nested ActiveRecord associations

I am having trouble figuring out how to retrieve an ActiveRecord object with deeply nested associations. Below is an example of what I am trying to achieve expressed as a JSON object.

Currently, my projects model has:

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

Expected Result (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": "[email protected]"
        },
        {
          "id": 2,
          "name": "Test User",
          "email": "[email protected]"
        }
      ]
    }
  ]
}

Example Code:

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

The closest I have managed to the desired result was by adding a groups method to the projects model to get all of the members:

Closest Result (JSON):

{
  "id": 7,
  "name": "Test Project",
  "description": "Project description",
  "groups": [
    {
      "id": 1,
      "name": "Admin",
      "email": "[email protected]"
    },
    {
      "id": 2,
      "name": "Test User",
      "email": "[email protected]"
    }
  ]
}

Example Code:

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

Upvotes: 0

Views: 521

Answers (2)

BroiSatse
BroiSatse

Reputation: 44675

You can do:

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}})

Upvotes: 0

adantj
adantj

Reputation: 466

You could try using activemodel serializers to include associated records.

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

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

You can check it out over at: 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.

Upvotes: 1

Related Questions