Blankman
Blankman

Reputation: 267020

How to include child associations when serializing to json?

Before using fast_jsonapi gem I was doing this:

render json: school.to_json(include: [classroom: [:students]])

My SchoolSerializer looks like:

class SchoolSerializer
  include FastJsonapi::ObjectSerializer
  attributes :name, :description, :classroom
end

How would I get the students included in the JSON result?

Also, the classroom association is including but it is displaying all the properties, is there a way to map the classroom property to a ClassroomSerializer ?

class School < ApplicationRecord
  belongs_to :classroom
end

class Classroom < ApplicationRecord
  has_many :students
end

Upvotes: 0

Views: 2898

Answers (2)

batshoes
batshoes

Reputation: 100

render json: SchoolSerializer.new(school, include: "classrooms.students")

The difference being the use of "include" when rendering the serializer. This tells the Serializer to add a key "included" to the returned JSON object.

class SchoolSerializer
  include FastJsonapi::ObjectSerializer

  belongs_to :classroom
  has_many :students, through: :classroom

  attributes :school_name, :description
end
StudentSerializer
  include FastJsonapi::ObjectSerializer

  belongs_to :classroom
  belongs_to :school

  attributes :student_name
end

render json: SchoolSerializer.new(school).serialized_json

will return a series of students with only the top level identifiers in the form

data: {
  id: "123"
  type: "school"
  attributes: {
    school_name: "Best school for Girls",
    description: "Great school!"
    ...

  },
  relationships: {
    students: [ 
      {
        id: "1234",
        type: "student"
      },
      { 
        id: "5678",
        type: "student"
      }
    ]
  }
}

whereas the include: "classroom.students" will return the full serialized Student Records in the form:

data: {
  id: "123"
  type: "school"
  attributes: {
    school_name: "Best school for Girls"
    ...

  },
  relationships: {
    classroom: {
      data: {
        id: "456",
        type: "classroom"
      }
    },
    students: [ 
      {
        data: {
          id: "1234",
          type: "student"
        }
      },
      { 
        data: {
          id: "5678",
          type: "student"
        }
      }
    ]
  },
  included: {
    students: {
      data { 
        id: "1234",
        type: "student",
        attributes: {
          student_name: "Ralph Wiggum",
          ...
        },
        relationships: {
          school: {
            id: "123",
            type: "school"
          },
          classroom: {
            id: "456",
            type: "classroom"
          }
        }
      }, 
      data: {
        id: "5678",
        type: "student",
        attributes: {
          student_name: "Lisa Simpson",
          ...
        },
        relationships: {
          school: {
            id: "123",
            type: "school"
          },
          classroom: {
            id: "456",
            type: "classroom"
          }
        }
      }
    },
    classroom: {
      // Effectively
      // ClassroomSerializer.new(school.classroom).serialized_json
    },
  }
}

Upvotes: 0

Alex Baidan
Alex Baidan

Reputation: 1075

class SchoolSerializer
  include FastJsonapi::ObjectSerializer
  attributes :name, :description

  belongs_to :classroom
end

# /serializers/classroom_serializer.rb
class ClassroomSerializer
  include FastJsonapi::ObjectSerializer
  attributes :.... #attributes you want to show
end

Also you can add additional association to your School model, to access Students. like this

has_many :students, through: :classroom

and then include it in School serializer directly.

Update: also please note that you can directly point to serializer class you need. (if you want to use class with different name from model as example).

class SchoolSerializer
  include FastJsonapi::ObjectSerializer
  attributes :name, :description

  belongs_to :classroom, serializer: ClassroomSerializer
end

Upvotes: 2

Related Questions