L o a d i n g
Laravel 8  Eloquent Relationships Tutorial   Many to Many Relationship BackEnd Development

Laravel 8 Eloquent Relationships Tutorial Many to Many Relationship

This is Part 3 of our Laravel 8 Eloquent Relationships Tutorial

Image description

Let's start by creating the database table necessary
php artisan make:migration create_subjects_table
php artisan make:migration create_student_subject_table

go to app/database/migrations:
subjects:

Schema::create('subjects', function (Blueprint $table) {
            $table >id();
            $table >string('name');
            $table >timestamps();
        });
Enter fullscreen mode Exit fullscreen mode

student_subject:

Schema::create('student_subject', function (Blueprint $table) {
            $table >id();
            $table >foreignId('student_id');
            $table >foreignId('subject_id');
            $table >string('grade') >nullable();
            $table >timestamps();
        });
Enter fullscreen mode Exit fullscreen mode

copy and save

run migration to create tables
php artisan migrate

check in your database if successful

Now let's create the model of comments
php artisan make:model Subject

Many to Many Relationships

Go to app/Models and open the student model and the comment models

define the many to many relationship
in Models/Student.php

public function subject()
    {
        return $this >belongstoMany('AppModelsSubject');
    }
Enter fullscreen mode Exit fullscreen mode

in Models/Subject.php

public function student()
    {
        return $this >belongstoMany('AppModelsStudent');
    }
Enter fullscreen mode Exit fullscreen mode

this will define the relationship between the two models

using the StudentController we made in part 1 lets create the function to create 3 subjects under 1 student

go to app/Http/Controllers/StudentController

public function store_subject(){

        $subject = new Subject;
        $subject >name = 'English';
        $subject >save();

        $subject = new Subject;
        $subject >name = 'Math';
        $subject >save();

        $subject = new Subject;
        $subject >name = 'Science';
        $subject >save();

        dd($subject);
    }
Enter fullscreen mode Exit fullscreen mode

this is for example purposes of creating multiple subjects only

create routes in app/routes/web.php

Route::get('/subjects/store', [StudentController::class,'store_subject']) >name('storeSubject');
Enter fullscreen mode Exit fullscreen mode

in your browser go to http://localhost:8000/students/store/comment to create 3 entry in the database

it should look similar to:

Image description

Using the two tables students and subjects lets save info to the student_subject table

check first if connection is successful by doing this

public function index(){
        $student = Student::find(1);
        dd($student >subject);
    }
Enter fullscreen mode Exit fullscreen mode

Result should be empty and similar to this:

Image description

it is empty because there are no associated subjects for any user

Now let's create associations from subjects to student

go to app/Http/Controllers/StudentController

public function store_student_subject(){

        $student = Student::find(1);

        $student >subject() >attach(1);

        dd($student);
    }
Enter fullscreen mode Exit fullscreen mode

create routes in app/routes/web.php

Route::get('/students/store/subject', [StudentController::class,'store_student_subject']) >name('storeStudentSubject');
Enter fullscreen mode Exit fullscreen mode

go to http://localhost:8000/students/store/subject to run the code

it should look similar to:

Image description

Hurray you have successfully attached one subject to one student!

Now go to http://localhost:8000/students to see if the the subject is connected to the student

Image description

Now let's create associations from subjects to student by passing an array

go to app/Http/Controllers/StudentController

public function store_student_subject(){
        $student = Student::find(1);
        $student >subject() >attach([2,3]);
        dd($student);
    }
Enter fullscreen mode Exit fullscreen mode

The result would be 2 rows of newly created associations for student id 1 with subject id 2 and 3

Now go to http://localhost:8000/students to see if the the student is now associated with 3 subjects

Result:
Image description

Now that we know how to add associations let's try and remove one!

Lets create the controller and route to detach associations

go to app/Http/Controllers/StudentController

public function detach_student_subject(){
        $student = Student::find(1);    
        $student >subject() >detach(1);
        dd($student);
    }
Enter fullscreen mode Exit fullscreen mode

create routes in app/routes/web.php

Route::get('/students/detach/subject', [StudentController::class,'detach_student_subject']) >name('detachStudentSubject');
Enter fullscreen mode Exit fullscreen mode

go to http://localhost:8000/students/detach/subject to run the code

it should look similar to:

Image description

Now go to http://localhost:8000/students to see if the the student is now only associated with 2 subjects
Result:

Image description

Hurray you have successfully detached one subject to one student!

Now lets try to use sync to simultaneously attack and detach subjects using 1 script

To test it out let's first add one more subject to be attached to the student

go to app/Http/Controllers/StudentController

public function store_subject(){
        $subject = new Subject;
        $subject >name = 'History';
        $subject >save();
        dd($subject);
    }
Enter fullscreen mode Exit fullscreen mode

go to http://localhost:8000/subjects/store to run the code

You should now have 4 subjects

And now lets try and use sync

go to app/Http/Controllers/StudentController

public function store_subject(){
        $subject = new Subject;
        $subject >name = 'History';
        $subject >save();
        dd($subject);
    }
Enter fullscreen mode Exit fullscreen mode

create routes in app/routes/web.php

Route::get('/students/sync/subject', [StudentController::class,'sync_student_subject']) >name('syncStudentSubject');
Enter fullscreen mode Exit fullscreen mode

Now the associations should only be subject id 2 and 3 but after we run this code the associations should be for subject 1, 2 and 4

1 and 4 was attached while 3 was dettached and 2 remained using sync

go to http://localhost:8000/students/sync/subject to run the code

then

go to http://localhost:8000/students to see if the the student is now associated with subjects 1, 2 and 4

Result:

Image description

Hurray you have successfully used sync to attach and detach subject to one student!

Now let's try toggle and do this quickly:
Create routes and controller:

public function toggle_student_subject(){
        $student = Student::find(1);    
        $student >subject() >toggle([1,2,3,4]);
        dd($student);
    }
...
Route::get('/students/toggle/subject', [StudentController::class,'toggle_student_subject']) >name('toggleStudentSubject');
Enter fullscreen mode Exit fullscreen mode

Toggle is used to do the opposite of the current status of a relationship.

For example:
Since 1,2 and 4 are currently attached, when you use toggle it will be detached and 3 will be attached.

Run this http://localhost:8000/students/toggle/subject and this http://localhost:8000/students and the result should be:

Image description

For best practices lets add the name of the pivot table to the model, and specify the two foreign keys with it (3rd = local key, 4th = foreign key)

go to Models/Student.php

public function subject()
    {
        return $this >belongstoMany('AppModelsSubject','student_subject','student_id','subject_id');
    }
Enter fullscreen mode Exit fullscreen mode

go to Models/Subject.php

public function student()
    {
        return $this >belongstoMany('AppModelsStudent','student_subject','subject_id','student_id');
    }
Enter fullscreen mode Exit fullscreen mode

It should work just like how it worked the first time!

Now let's try and add one more column in the pivot table.
Take note that we have already 1 extra column grade and we will now use it.

go to Models/Student.php

public function subject()
    {
        return $this >belongstoMany('AppModelsSubject','student_subject','student_id','subject_id')
             >withPivot('grade');
    }
Enter fullscreen mode Exit fullscreen mode

go to Models/Subject.php

public function student()
    {
        return $this >belongstoMany('AppModelsStudent','student_subject','subject_id','student_id')
             >withPivot('grade');
    }
Enter fullscreen mode Exit fullscreen mode

Now lets try and add grades to the student_subject table
Add this in controller and routes

public function grade_student_subject(){
        $student = Student::find(1);
        $subject = Subject::find(2);    
        $student >subject() >save($subject,['grade'=>90]);
        dd($student);