I have two articles that explain the one-to-one and one-to-many relationships in Laravel, so in this article I’ll explain about many-to-many relationships. As you know, we can find so many cases where we can implement this relationship such as articles with their categories/tags, users with their roles/profiles, and so on. So, this relationship is more common to be used in real projects but is more complex than the other two relationships because it requires a pivot table.
As always, I have prepared the Github and postman API collection below and here’s the outline of this article:
- Many-to-Many ER Diagram
- Database Migration
- Eloquent ORM Model
- Controller & Routing
Many-to-Many ER Diagram
In this article, we’ll use this ER Diagram below to demonstrate the many-to-many relationship:
Based on our diagram, we have 3 tables now. So we have the users and events tables and store its relationship in a pivot table named event_user. The event_user table will store the data when a user book some events so, a user can have multiple events to book and vice versa, an event can be booked my multiple users.
First thing first, let’s start by creating a project using composer.
composer create-project --prefer-dist laravel/laravel many-to-many
Once complete, you will find the migration tables inside database/migrations/ folder. There, you’ll find a create_user_table.php and let’s use this for our users table. So we will create another two tables.
php artisan make:migration create_events_table
php artisan make:migration create_event_user_table
If you’re wondering why the table event_user name is weird, it’s because I used the Laravel naming convention when creating a pivot table name. The naming convention for a pivot table is: put together the two table names in a singular form in alphabetical order. This naming convention will make it easier for us to set up the model later.
Let’s open the database/migrations/create_events_table.php.
Nothing special here except, the primary key for event_user table. I use $table->primary([‘user_id’,’event_id’]) it means that, the combination between user_id and event_id must be unique. It doesn’t make sense if a user can book same multiple events right? So that’s why I use that combination for the primary key.
Don’t forget to set up your database name in .env file of your project, and run the migration
php artisan migrate
Eloquent ORM Model
So now, we have 3 new tables appear in our database, but we only need 2 models in this project. In this case, we don’t need to create a model for event_user table because Laravel will store the many-to-many relationships automatically in our pivot table. Let’s create the Event model
php artisan make:model Event
Then open the app/Event model.
For reading and storing the relationship between users table, we use belongsToMany() function without specifying the pivot table name because we are following the naming convention for pivot table. If you have a pivot table without following the naming convention, then you must specify the pivot table name inside the second argument of belogsToMany(). So the function will become like, belongsToMany(‘App\User’,’anotherpivottable’). But again, in this case we don’t need to specify the second argument because our pivot table name has following the naming convention.
There is nothing special in the User model, we just added a new function called events() at the bottom.
Controller & Routing
So let’s setup the controllers by creating them first.
php artisan make:controller UserController -r
php artisan make:controller EventController -r
php artisan make:controller UserEventController -r
php artisan make:controller EventUserController -r
Now we have 4 controllers inside app/Http/Controllers. Let’s open the UserController.
As you can see, we have a function named book_event() there. When we are storing the relationship, it’s very easy with Eloquent ORM Laravel. We can just call $user->events()->save($event, array(‘note’ => $note)) function without specifying anything about our pivot table. In addition, I add another column named note in the pivot table and that’s the way on how storing this note column into our pivot table. Super easy right?
Then let’s configure the EventController.
For the Event controller, there’s nothing special here. We only use index, store, and show methods. Let’s continue with UserEventController.
We only have 1 function here that’s the index. It’s super easy when we are accessing the events for a specific user with $user->events function. Of course, Laravel will do the rest. Next the EventUserController,
Again, we only need the index function here for showing all users that booked a specific event. We only need to call $event->users function to get all of the users. Last thing to do, let’s set up the API routing.
In this route, we use Route::resource() function so that Laravel will automatically create the routes for us. If you want to know what routes that we have, just type this in the command prompt:
php artisan route:list
Then it’s done. We have successfully build the many-to-many relationship with Laravel. It’s super easy right? I hope this article can be a good reference for you when building this type of relationship. Thank you
Postman API Collection: https://www.getpostman.com/collections/a2fb13620a2532e0f298