How to access a foreign key relationship in many to many pivot table in Laravel?

Viewed 76

I have the following relationships in a Laravel 9 project:

Student:

class Student extends Model
{
    public function grade()
    {
        return $this->belongsTo(Grade::class);
    }

    public function protocols()
    {
        return $this->belongsToMany(Protocol::class, 'protocol_student')>withPivot('current_grade_id', 'new_grade_id');
    }
}

Protocol:

class Protocol extends Model
{

   public function students()
    {
        return $this->belongsToMany(Student::class, 'protocol_student')->withPivot('current_grade_id', 'new_grade_id');
    }
}

And the many to many relationship has the following database structure which contains two pivot fields that are actually foreign keys:

Schema::create('protocol_student', function (Blueprint $table) {
            $table->id();

            $table->foreignId('protocol_id')->constrained('protocols')->cascadeOnDelete();
            $table->foreignId('student_id')->constrained('students')->cascadeOnDelete();

            $table->foreignId('current_grade_id')->nullable()->constrained('grades')->cascadeOnDelete();
            $table->foreignId('new_grade_id')->nullable()->constrained('grades')->cascadeOnDelete();

            $table->timestamps();
        });

My question is:

How to make the relationship so I can access new grades with:

$protocol->students->first()->pivot->newGrade->name

At the moment I can reach the "new_grade_id" but I can't reach the relationship I am getting:

$protocol->students->first()->pivot->new_grade_id but I cant access a relationship with grade.

1 Answers

I found the solution here in the Laravel documentation.

I have to make another class

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\Pivot;

class ProtocolStudent extends Pivot
{
    public function currentGrade()
    {
        return $this->belongsTo(Grade::class, 'current_grade_id');
    }

    public function newGrade()
    {
        return $this->belongsTo(Grade::class, 'new_grade_id');
    }
}

Then when this new class created I have to tie it to the pivot relationship in the Protocol/Students models like this:

public function students()
    {
        return $this->belongsToMany(Student::class, 'protocol_student')
                    ->withPivot('current_grade_id', 'new_grade_id')
                    ->using(ProtocolStudent::class);
    }

And now all is done I am able to access a relationship like this:

$protocol->students->first()->pivot->newGrade->name

Related