cloudcreativity/laravel-json-api

[Question] How do I show my relationships in included section?

acrespo123 opened this issue · 7 comments

I am working with a school system.

I need to return the list of students in a Controller method but I can't return it. I have the students list in cohort and activity_assistences resources.

In my activity Schema:

    public function getIncludePaths()
    {
        return ['cohort', 'activity_assistences'];
    }

In my activity Adapter:
protected $defaultWith = ['cohort', 'activities_assistences'];

In my activity Validator:

    protected $allowedIncludePaths = [
        'cohort',
        'teacher',
        'activity_assistences',
    ];

My ActivitiesController createAssistences method:

    public function createAssistences(Activity $activity): Response
    {
        $students = $activity->cohort->students;
        $assistences = [];

        return $this->reply()->updated($resource=$activity);
    }

Returned json:

{
    "data": {
        "type": "activities",
        "id": "16",
        "attributes": {
            ...
        },
        "relationships": {
            "cohort": {
                "data": {
                    "type": "cohorts",
                    "id": "3"
                }
            },
            "activity_assistences": {
                "data": [
                    ....
                ]
            }
        },
        "links": {
            "self": "http://localhost:8000/api/v1/activities/16"
        }
    },
    "included": [
        {
            "type": "cohorts",
            "id": "3",
            "attributes": {
                ....
            },
            "relationships": {
                "activities": [],
                "course": [],
                "students": [],
                "teacher": []
            }
        },
        {
            "type": "activity_assistences",
            "id": "505",
            "attributes": {
                ....
            },
            "relationships": {
                "activity": [],
                "student": [],
                "teacher": []
            }
        }
    ]
}

Sorry, not totally clear what you're trying to do.

You've configured the cohort and activity_assistences default include paths - the JSON has included those.

If you then need further relationships, e.g. student on the cohorts resource, you'd have to set the default include paths to cohort.student.

Is that what you are after?

Thanks for the reply, I need to return this:

    "included": [
        {
            "type": "cohorts",
            "id": "3",
            "attributes": {
                ....
            },
            "relationships": {
                "activities": [],
                "course": [],
                "students": [], -> This
                "teacher": [] -> This
            }
        },
        {
            "type": "activity_assistences",
            "id": "505",
            "attributes": {
                ....
            },
            "relationships": {
                "activity": [],
                "student": [],
                "teacher": []
            }
        }
    ]

Actually those relationship values are not valid - the students member in the cohorts resource should be an object, not an array.

The problem is in your cohorts schema. Can you share the getRelationships() method?

Cohorts schema:

    public function getRelationships($resource, $isPrimary, array $includeRelationships)
    {
        return [
            'activities' => [
                self::SHOW_DATA => isset($includeRelationships['activities']),
                self::DATA => function () use ($resource) {
                    return $resource->activities;
                },
            ],
            'course' => [
                self::SHOW_DATA => isset($includeRelationships['course']),
                self::DATA => function () use ($resource) {
                    return $resource->course;
                },
            ],
            'students' => [
                self::SHOW_DATA => isset($includeRelationships['students']),
                self::DATA => function () use ($resource) {
                    return $resource->students;
                },
            ],
            'teacher' => [
                self::SHOW_DATA => isset($includeRelationships['teacher']),
                self::DATA => function () use ($resource) {
                    return $resource->teacher;
                },
            ]
        ];
    }

So yeah, you'd need to update your include paths to cohorts.course,cohorts.students,cohorts.teacher if you want all those relationships shown. Does it work if you do that?

thanks a lot, it works

Great, glad to hear that!