Laravel 11 Many to Many Eloquent Relationship Tutorial

By Hardik Savani September 4, 2024 Category : Laravel

In this post, I will show you many to many relationship in laravel 11 application. we will use belongsToMany() eloquent method for many to many relationship.

In Laravel, a many-to-many relationship between tables like "users" and "roles" is when each user can have multiple roles, and each role can belong to multiple users. The "role_user" table acts as a bridge, storing the connections between users and roles. This setup allows for flexible role assignments, where users can have different roles, and roles can be shared among multiple users, making it easier to manage permissions and access levels in applications.

laravel 11 many to many relationship

Many-to-many relationship will use "belongsToMany()" for relation.

Create Migrations:

Now we have to create migrations for the "users," "roles," and "role_user" tables. We will also add foreign keys to the "users" and "roles" tables. So let's create them as follows:

users table migration:

<?php
  
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};

roles table migration:

<?php
  
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up(): void
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }
  
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down(): void
    {
        Schema::dropIfExists('roles');
    }
};

role_user table migration:

<?php
  
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up(): void
    {
        Schema::create('role_user', function (Blueprint $table) {
            $table->foreignId('user_id')->constrained('users');
            $table->foreignId('role_id')->constrained('roles');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down(): void
    {   
        Schema::dropIfExists('role_user');
    }
};

Create Models:

Here, we will create User, Role and UserRole table model. we will also use "belongsToMany()" for relationship of both model.

User Model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class User extends Authenticatable
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * The roles that belong to the user.
     */
    public function roles(): BelongsToMany
    {
        return $this->belongsToMany(Role::class, 'role_user');
    }
}

Role Model:

<?php
  
namespace App\Models;
  
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  
class Role extends Model
{
    use HasFactory;
  
    /**
     * The users that belong to the role.
     */
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class, 'role_user');
    }
}

UserRole Model:

<?php
  
namespace App\Models;
  
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
  
class UserRole extends Model
{
    use HasFactory;
      
}

Retrieve Records:

$user = User::find(1);  
 
dd($user->roles);

$role = Role::find(1);  
 
dd($role->users);

Create Records:

$user = User::find(2);  
 
$roleIds = [1, 2];
$user->roles()->attach($roleIds);

$user = User::find(3);  
 
$roleIds = [1, 2];
$user->roles()->sync($roleIds);


$role = Role::find(1);  
 
$userIds = [10, 11];
$role->users()->attach($userIds);

$role = Role::find(2);  
 
$userIds = [10, 11];
$role->users()->sync($userIds);

I hope you understand of many to many relationship...

Shares