در لاراول، روابط چند به چند (Many-to-Many) به شما این امکان را میدهد که دو مدل مختلف به یکدیگر ارتباط داشته باشند و یک رکورد در مدل اول میتواند به چندین رکورد در مدل دوم مرتبط باشد و برعکس. این نوع ارتباط معمولاً در جداول میانه (Pivot Tables) ذخیره میشود.
مفهوم رابطه چند به چند:
فرض کنید یک اپلیکیشن داریم که در آن کاربران میتوانند چندین نقش (Role) داشته باشند و در عین حال هر نقش میتواند به چندین کاربر اختصاص داده شود. این نوع رابطه، یک رابطه چند به چند است که میتواند به راحتی در لاراول با استفاده از جداول میانه پیادهسازی شود.
🛠️ نحوه پیادهسازی روابط Many to Many در لاراول
1. ساخت مدلها و جدولها
برای پیادهسازی این نوع رابطه، شما به دو مدل و یک جدول میانه نیاز دارید. در مثال ما، مدلها User
و Role
هستند.
1.1 ایجاد جدولهای users
, roles
و جدول میانه role_user
ابتدا باید جدولهای مربوط به هر مدل و جدول میانه را در مایگریشنها ایجاد کنیم.
-
جدول
users
:
phpSchema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
-
جدول
roles
:
phpSchema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
-
جدول میانه
role_user
:
phpSchema::create('role_user', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->foreignId('role_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
در اینجا از جدول role_user
بهعنوان جدول میانه برای ایجاد ارتباط بین users
و roles
استفاده میکنیم.
2. تعریف روابط در مدلها
2.1 مدل User
:
برای تعریف رابطه Many to Many در مدل User
، از متد belongsToMany
استفاده میکنیم.
phpuse Illuminate\Database\Eloquent\Model;
class User extends Model
{
// تعریف رابطه Many to Many با مدل Role
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
2.2 مدل Role
:
برای تعریف رابطه Many to Many در مدل Role
، مشابه مدل User
از متد belongsToMany
استفاده میکنیم.
phpuse Illuminate\Database\Eloquent\Model;
class Role extends Model
{
// تعریف رابطه Many to Many با مدل User
public function users()
{
return $this->belongsToMany(User::class);
}
}
3. استفاده از روابط Many to Many
3.1 پیوند دادن رکوردها
برای پیوند دادن یک کاربر به یک یا چند نقش، از متد attach()
استفاده میکنیم. این متد میتواند به شما اجازه دهد که رکوردهای جدید را در جدول میانه role_user
وارد کنید.
php$user = User::find(1);
$user->roles()->attach(1); // اضافه کردن نقش با شناسه 1 به کاربر
اگر بخواهید چندین نقش را به یک کاربر اضافه کنید:
php$user->roles()->attach([1, 2, 3]); // اضافه کردن نقشهای با شناسههای 1، 2 و 3 به کاربر
3.2 حذف پیوندها
برای حذف یک پیوند خاص از جدول میانه، میتوانید از متد detach()
استفاده کنید.
php$user->roles()->detach(1); // حذف نقش با شناسه 1 از کاربر
برای حذف تمام پیوندها بین کاربر و نقشها:
php$user->roles()->detach(); // حذف همه نقشها از کاربر
3.3 بررسی وجود پیوند
برای بررسی اینکه آیا یک پیوند خاص در جدول میانه وجود دارد یا خیر، میتوانید از متد contains()
استفاده کنید:
phpif ($user->roles->contains(1)) {
// نقش با شناسه 1 به کاربر تعلق دارد
}
3.4 بهروزرسانی پیوندها
برای بهروزرسانی پیوندها، از متد sync()
استفاده میکنیم. این متد نقشهای کاربر را بهروزرسانی میکند و تمام نقشهای قبلی را حذف کرده و نقشهای جدید را اضافه میکند.
php$user->roles()->sync([1, 2]); // فقط نقشهای با شناسه 1 و 2 را به کاربر اختصاص میدهد
اگر بخواهید نقشهای قبلی را نگهدارید و فقط نقشهای جدید را اضافه کنید، از متد syncWithoutDetaching()
استفاده کنید:
php$user->roles()->syncWithoutDetaching([1, 3]); // فقط نقشهای جدید را اضافه میکند بدون حذف نقشهای قبلی
⚙️ استفاده از دادههای اضافی در جدول میانه (Pivot Data)
گاهی اوقات ممکن است بخواهید اطلاعات اضافی را در جدول میانه ذخیره کنید. به عنوان مثال، ممکن است بخواهید زمانی که یک کاربر به یک نقش اختصاص داده میشود، تاریخی را ثبت کنید.
1. اضافه کردن فیلدهای اضافی به جدول میانه
ابتدا باید فیلدهای اضافی را به جدول role_user
اضافه کنید:
phpSchema::table('role_user', function (Blueprint $table) {
$table->date('assigned_at')->nullable(); // اضافه کردن فیلد assigned_at
});
2. دسترسی به دادههای اضافی در جدول میانه
برای دسترسی به دادههای اضافی در جدول میانه، از متد withPivot()
استفاده میکنیم.
php// دریافت نقشهای یک کاربر به همراه دادههای اضافی
$user = User::find(1);
foreach ($user->roles as $role) {
echo $role->pivot->assigned_at; // دسترسی به فیلد assigned_at
}
3. اضافه کردن دادهها به جدول میانه هنگام پیوند دادن
برای اضافه کردن دادهها به جدول میانه هنگام پیوند دادن، از متد attach()
با آرایه استفاده میکنیم:
php$user->roles()->attach(1, ['assigned_at' => now()]); // اضافه کردن تاریخ به جدول میانه هنگام پیوند دادن
✅ مزایای استفاده از روابط Many to Many
-
انعطافپذیری بالا: این نوع رابطه به شما این امکان را میدهد که رکوردهای مختلف را بهطور متقابل به هم پیوند دهید و به راحتی دادهها را مدیریت کنید.
-
افزودن دادههای اضافی در روابط: از آنجا که جداول میانه میتوانند فیلدهای اضافی داشته باشند، میتوانید اطلاعاتی مثل تاریخ ایجاد پیوند یا وضعیت را ذخیره کنید.
-
سهولت در پیادهسازی: تعریف روابط و کار با آنها در لاراول بسیار ساده و واضح است.
-
مقیاسپذیری: لاراول بهطور کامل از جداول میانه پشتیبانی میکند و به شما این امکان را میدهد که بهراحتی حجم زیادی از دادهها را مدیریت کنید.
🛠️ جمعبندی
در لاراول، استفاده از روابط Many to Many با استفاده از جداول میانه بسیار ساده است. با تعریف متد belongsToMany
در مدلها و ایجاد جدول میانه مناسب، میتوانید به راحتی رکوردهای مرتبط را پیوند دهید، حذف کنید و حتی دادههای اضافی را ذخیره کنید. این نوع رابطه برای ساخت ارتباطات پیچیده بین مدلها در اپلیکیشنهای بزرگ بسیار مفید است.