laravel-json-api / laravel

JSON:API for Laravel applications
MIT License
552 stars 42 forks source link

Model attributes are empty, in relationship method, over the api. #296

Open ahmed-osama-saad opened 1 month ago

ahmed-osama-saad commented 1 month ago

I have relationship defined on WorkoutResults model

public function unfinishedExercises()
    {
        $exercises = $this->exercises();
        $id = $this->id;

        return $exercises->whereDoesntHave('exercisesResults', function ($query) use ($id) {
            $query->where('workout_result_id', $id);
        });
    }

In WorkoutResultSchema, I define the relationship field

HasMany::make('unfinished_exercises', 'unfinishedExercises')->type('exercises'),

The issue I'm facing:

After some debugging, I found that the problem only occurs when this relationship is requested over the api. When using the relationship in tinker, $this is defined correctly, and the filtering works as expected.

If I request this relationship from workout-results/:id?include=unfinished_exercise endpoint, the filtering doesn't happen, I get all exercises.

lindyhopchris commented 1 month ago

Hi. Yeah I don't actually think this does work in Tinker. It would need to work via Eager Loading in Tinker.

What happens if yo try this in Tinker:

$models = WorkoutResult::query()->with('unfinishedExercises')->get();

Basically, you can't use $this->id in a relationship method, as the relationships are not always loaded from a specific model - otherwise you'd get N+1 problems.

We use eager loading, so that we don't get N+1 problems.