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

rojonunoo's avatar

Has Many through relationship / Many to Many Relationship

I am working on a little school project where i have three models

Class/Grade has many students

A student belongs to One Class

Students have many subjects

and am a bit confused as to what kind of relationship will this be . any answer with some more explanation on Relationships will do thanks in advance

0 likes
6 replies
domioanna's avatar

Are the Grade - Subject related at all? Or do they need to be?

davielee's avatar
davielee
Best Answer
Level 11

Hey @rojonunoo, let's walk through it step by step. There is no point in getting over complicated with these relationships unless you absolutely have to.

To start off with, a Grade will have many Students.

App\Grade

public function students()
{
    return $this->hasMany(Student::class);
}

Next, a Student belongs to a Grade.

App\Student

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

Next, a Student has many Subjects.

App\Student

public function subjects()
{
    return $this->belongsToMany(Subject::class);
}

Finally, a Subject has many Students.

App\Subject

public function students()
{
    return $this->belongsToMany(Student::class);
}

That would be the simplest way to set it up. Let's take a look at the basic table structure that would entail (shown from within the Schema::create() callback).

grades

$table->increments('id');
$table->timestamps();

students

$table->increments('id');
$table->unsignedInteger('grade_id');
$table->timestamps();

subjects

$table->increments('id');
$table->timestamps();

student_subject

$table->increments('id');
$table->unsignedInteger('student_id');
$table->unsignedInteger('subject_id');
$table->timestamps();

One thing you might be overlooking (or forgot to mention) is that a Grade will probably have many Subjects correct? In that case, we would need to add another pivot table. First let's take a look at the new/revised relationships.

App\Grade

public function subjects()
{
    return $this->belongsToMany(Subject::class);
}

App\Subject

public function grades()
{
    return $this->belongsToMany(Grade::class);
}

That would allow the Subject model to belong to both the Grade and the Student without having to mess with polymorphic relations and make a mess of your DB. This would just add the following migration.

grade_subject

$table->increments('id');
$table->unsignedInteger('grade_id');
$table->unsignedInteger('subject_id');
$table->timestamps();
3 likes
rojonunoo's avatar

@craigpaul thanks so much .. ok i was making things more complicated there thanks so much for the explanation . really appreciate the help

rojonunoo's avatar

@craigpaul

[Illuminate\Database\QueryException] SQLSTATE[HY000]: General error: 1005 Can't create table sas.#sql-8b3_67b (errno: 150 "Foreign key constraint is incorrectly formed") (SQL: alter table students add constraint students_grade_id_foreign foreign key (grade_id) references grades (id))

when i try to migrate on my students table

$table->engine = 'InnoDB';

    $table->increments('id');
    $table->unsignedInteger('grade_id')->nullable();
    $table->string('name');
    $table->date('dob');
    $table->string('last_school_attended');
    $table->string('avatar')->default();
    $table->softDeletes('deleted_at');
    $table->timestamps();


    $table->foreign('grade_id')
        ->references('id')->on('grades')
        ->onDelete('cascade');

i have tried everything possible but it still gets stuck here

Please or to participate in this conversation.