cloudcreativity / laravel-json-api

JSON API (jsonapi.org) package for Laravel applications.
http://laravel-json-api.readthedocs.io/en/latest/
Apache License 2.0
778 stars 109 forks source link

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

Closed acrespo123 closed 3 years ago

acrespo123 commented 3 years ago

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": []
            }
        }
    ]
}
lindyhopchris commented 3 years ago

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?

acrespo123 commented 3 years ago

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": []
            }
        }
    ]
lindyhopchris commented 3 years ago

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?

acrespo123 commented 3 years ago

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;
                },
            ]
        ];
    }
lindyhopchris commented 3 years ago

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?

acrespo123 commented 3 years ago

thanks a lot, it works

lindyhopchris commented 3 years ago

Great, glad to hear that!