Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Mithridates's avatar

Creating a belongs to many relationship

I have a kinda unique situation here, I have 3 models: Degree, Student and Consultant.

There is a many to many rel between a student and a consultant. Also there is a many to many rel between degree and student.

I could have 2 pivot table for each one of those above relations, BUT what important here is, is that: a student in a specific degree can have 1 consultant. In other words creating 2 separate pivot table, doesn't give me the information which consultant is for what degree for a specific user.

I can think of 2 solutions here:

The first one is creating a pivot table with 3 foreign keys like:

student_id  |  degree_id  |  consultant_id

this way I could know who is the student's consultant for a specific degree.

But is this way, a standard way of architecturing database? Also, Should I create a Pivot model for this? What would be the code snippet look like?

The other approach I can think of is that create 2 separate pivot tables, and reference id of one pivot table in the other one. So this would look like something like: degree_student: student_id | degree_id consultant_student: student_id | consultant_id | **degree_student_id**

Again, is this a standard approach? Should I create a Pivot model for this?

For final discussion, I would embrace any other solution suggestions that are better(/standard).

0 likes
3 replies
Dunsti's avatar

I don't get it completely:

There is a many to many rel between a student and a consultant. Also there is a many to many rel between degree and student.

Does that mean, that a student can have more than one consultant, and more than one degree?

If the student has exactly one consultant and exactly one degree, I would suggest a hasManyThrough relationship.

https://laravel.com/docs/5.4/eloquent-relationships#has-many-through

Mithridates's avatar

@Dunsti by logic of the application, a student in a specific degree can have exactly 1 consultant. of course that student (Say student a) can have another consultant in another degree.

Does that mean, that a student can have more than one consultant, and more than one degree? yes a student can have more than 1 degree in the system, and can have more than 1 consultant.

The only requirement is that for a specific degree and a specific student there can be exactly 1 consultant.

How would you database design look like, also your relationships in the models.

Can elaborate a bit? tnx

Dunsti's avatar

I would suggest the following:

you have three tables students, degrees and consultants

migration looks something like this:

Schema::create('students', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});
Schema::create('degrees', function (Blueprint $table) {
    $table->increments('id');
        $table->string('name');
        $table->timestamps();
});
Schema::create('consultants', function (Blueprint $table) {
    $table->increments('id');
        $table->string('name');
        $table->timestamps();
});

the pivot table goes like this:

Schema::create('degree_student', function (Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('consultant_id');
    $table->unsignedInteger('degree_id');
    $table->unsignedInteger('student_id');
    $table->timestamps();

    $table->foreign('consultant_id')->references('id')->on('consultants');
    $table->foreign('degree_id')->references('id')->on('degrees');
    $table->foreign('student_id')->references('id')->on('students');
});

note that the pivot-table is named degree_student. This is because we make a many-to-many-relationship between students and degrees.

The Models then look like this:

class Student extends Model
{
    public function degrees()
    {
        return $this->belongsToMany('App\Degree')
        ->using('App\DegreeStudent')
        ->withPivot('consultant_id');
    }
}
class Degree extends Model
{
    public function students()
    {
        return $this->belongsToMany('App\Student')
            ->using('App\DegreeStudent')
            ->withPivot('consultant_id');
    }
}
class Consultant extends Model
{
    public function degree_student()
    {
        return $this->hasMany('App\DegreeStudent');
    }
}

And we need an additional Model for the pivot-table:

use Illuminate\Database\Eloquent\Relations\Pivot;

class DegreeStudent extends Pivot
{
    public function consultant()
    {
        return $this->belongsTo('App\Consultant');
    }
}

note that this Model extends Pivot instead of Model !

With this you can access the consultant for a student in a specific degree like this:

App\Student::find(1)->degrees()->find(1)->pivot->consultant()->get()

I hope I don't have any typos in here, and I also hope, you get the point with this solution.

[EDIT] I must admit, that this solution doesn't give you all possibilities. You can't find students and degrees for a given consultant. Maybe you need to make many-to-many-relationships for consultant-student and consultant-degree as well. Good Luck! :)

Please or to participate in this conversation.