Laravel many to many relationship

In this article let’s understand many-to-many relationship in Laravel.

Laravel provides many relationship to work with multiple tables and one of them is many-to-many relationship.

So, when one record of the table is associated with many records of another table but another tables one record will also be associated with many record from first table.

The associations between the entities in this kind of relationship must be stored in an intermediate table, also referred to as a pivot table or junction table.

Check below graphics to understand it in simple scenario.

What you can see from graphics is one student can have many courses and one course can have many student association.

Let’s understand it through example where we have:

  • Two models : Student and Course
  • Two migrations: For Student and Course

Create them using below artisan command :

php artisan make:model Student -m
php artisan make:model Course -m
php artisan make:migration create_students_courses_table

This will create two models and two migrations as below:

app/Models/
    Student.php
    Course.php

database/migrations/
    ***_create_students_table.php
    ***_create_courses_table.php
    ***_create_students_courses_table.php

Open ***_create_students_table.php and modify as blow:

public function up(): void
    {
       Schema::create('students', function (Blueprint $table) {
          $table->id();
          $table->string("name");
          $table->string("standard");
         $table->timestamps();
       });
    }

Check ***_create_courses_table.php and modify as blow:

public function up(): void
    {
       Schema::create('courses', function (Blueprint $table) {
           $table->id();
           $table->string("name");
           $table->string("year");
           $table->timestamps();
       });
    }

Check ***_create_students_courses_table.php and modify as blow:

This is a pivot table needs to store the associations between both tables.

public function up(): void
    {
       Schema::create('students_courses', function (Blueprint $table) {
        $table->bigIncrements('id');        
        $table->string('student_id');
        $table->foreign('student_id')->references('id')->on('students')->onDelete('cascade');
        $table->string('course_id');
        $table->foreign('course_id')->references('id')->on('courses')->onDelete('cascade');
    });
}

Open app/Models/Student.php and modify as blow:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Student extends Model
{
    use HasFactory;
    public function courses()
    {
        return $this->belongsToMany(Courses::class);
    }
}

Check app/Models/Course.php and modify as blow:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Course extends Model
{
    use HasFactory;
    public function students()
    {
        return $this->belongsToMany(Student::class);
    }
}

A relationship between both the models will be the belongsToMany method

Run Migrations:

php artisan migrate

Use below methods in your controller to check how many-to-many relationship works:

//Fetch

$student = Student::find(1);
$courses = $student->courses;
foreach ($courses as $course) {
    echo $courses->name . ': ' . $courses->year. "\n";
}

//create
$student = Student(['name' => 'CSP']);
$student->save();

$course1 = new Course(['name' => 'PHP']);
$course2 = new Course(['name' => 'Javascript']);

$student->courses()->saveMany([$course1, $course2]);

//delete
$student->courses()->detach($course1Id); 

That’s it on Laravel many to many relationship. Hope this finds you helpful.

See other articles on Laravel here.