In this article, I will elucidate the intricacies of the many-to-many relationship within a Laravel 11 framework. To accomplish this, we shall employ the eloquent method "belongsToMany()" for such relational dynamics.
Within the Laravel ecosystem, the notion of a many-to-many relational construct, as exemplified by the junction between "users" and "roles," delineates a scenario wherein each user may hold sway over myriad roles, while concurrently each role can be attributed to a multitude of users. The intermediary table, christened "role_user," plays a pivotal role in interlinking users and roles, thereby furnishing a conduit for such multifaceted associations. This configuration engenders a pliable system for role allocation, affording users diverse roles while enabling roles to be communally shared amongst a cohort of users. This, in turn, facilitates the streamlined management of permissions and access hierarchies within applications.
The establishment of a many-to-many relationship necessitates the utilization of the "belongsToMany()" method for establishing the requisite connections.
Initiating Migrations:
Our initial step entails the formulation of migrations for the pertinent tables, namely "users," "roles," and "role_user." Additionally, we shall incorporate foreign keys within the "users" and "roles" tables. The ensuing delineations expound upon this endeavor:
Migration for the users
table:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Execute the migration.
*
* @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 migration.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('users');
}
};
Migration for the roles
table:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Execute the migration.
*
* @return void
*/
public function up(): void
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
/**
* Reverse the migration.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('roles');
}
};
Migration for the role_user
table:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Execute the migration.
*
* @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 migration.
*
* @return void
*/
public function down(): void
{
Schema::dropIfExists('role_user');
}
};
Creation of Models:
Subsequently, we proceed to craft models for the User
, Role
, and UserRole
tables, wherein we shall integrate the belongsToMany()
relationship into their respective constructs.
User Model:
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:
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:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserRole extends Model
{
use HasFactory;
}
Retrieval of Records:
$user = User::find(1);
dd($user->roles);
$role = Role::find(1);
dd($role->users);
Creation of 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);
In conclusion, it is my fervent hope that the elucidation provided herein has afforded you a comprehensive understanding of the intricacies inherent within the realm of many-to-many relationships.