در این مقاله تمام موارد در رابطه با راه اندازی روابط بین جداول گفته شده است.
تمام لاراول کارها و کسانی که با لاراول کار میکنند حداقل یک بار روابط بین جداول را اجرا کرده اند. اما موارد زیادی وجود دارد که ممکن است هنگام اجرای یک رابطه با آن رو به رو شوید. از آنجایی که انواع روابط وجود دارند، شما از کجا میفهمید در چه زمانی از کدام از آنها استفاده کنید؟
اگر چگونگی روابط در لاراول را نمیدانید، نگران نباشید. پس از خواندن این مقاله درک بهتری از آن پیدا میکنید
پس با ما همراه باشید...
برای پاسخ به این سوال ابتدا باید بدانید که انواع رابطه های موجود چیست.
سه نوع رابطه وجود دارد:
انواع مختلف روابط را یکی یکی مرور می کنیم و توضیح می دهیم که چه زمانی از آنها استفاده کنیم.
رابطه یک به یک ساده ترین نوع رابطه ای است که وجود دارد. این نوع رابطه به این معنی است که مدل نوع A فقط به یک مدل از نوع B مرتبط و یا لینک شود و بالعکس. به عنوان مثال رابطه بین مدل کاربر (User) و مدل گذرنامه (Passport) یک رابطه یک به یک است. کاربر میتواند فقط یک گذرنامه داشته باشد و یک گذرنامه فقط متعلق به یک کاربر است.
بیایید نگاهی بیندازیم که چگونه این نوع رابطه را به صورت کد تعریف می کنیم.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { public function passport() { return $this->hasOne(App\Passport::class); } }
در مدل User ما از متدی با نام passport استفاده میکنیم. ما با استفاده از متد hasOne به لاراول میگوییم مدل کاربر یک گذرنامه دارد.
توجه: به این موضوع توجه داشته باشید که تمام متد هایی مثل hasOne که برای تعاریف روابط بین جداول هستند یک سری آرگون های اضافه و اختیاری دارند. این آرگومان ها برای تعریف کلید محلی و کلید خارجی استفاده میشود. به طور پیش فرض، لاراول تصور میکند که شما هنگام تعریف migration های جدول passport از فیلدی به نام user_id استفاده کرده اید.
در مدل Passport ما معکوس رابطه را میتوانیم تعریف کنیم. در واقع ما به مدل Passport میگوییم که بداند متعلق به یک کاربر است. ما این کار را با استفاده از متد belongsTo انجام میدهیم
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Passport extends Model { public function user() { return $this->belongsTo(App\User::class); } }
رابطه بعدی که می توانید در لاراول تعریف کنید یک رابطه یک به چند است. این نوع رابطه به این معنی است که یک مدل از نوع A ممکن است به چندین مدل از نوع B مرتبط شود اما مدل نوع B فقط به یک مدل از نوع A تعلق دارد.
به عنوان مثال ، رابطه بین مدل کاربر و مدل فاکتور یک رابطه یک به چند است. یک کاربر می تواند چندین فاکتور داشته باشد ، اما فاکتور فقط به یک کاربر تعلق دارد. یک کاربر می تواند چندین فاکتور داشته باشد ، اما یک فاکتور فقط به یک کاربر تعلق دارد.
برای پیاده سازی این نوع رابطه از کد زیر استفاده میکنیم
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { public function invoices() { return $this->hasMany(App\Invoice::class); } }
به نظر می رسد تقریبا مانند کدی است که قبلاً برای تعریف رابطه یک به یک دیدیم ، درست است؟
فقط بجای استفاده از متد hasOne از متد hasMany استفاده کرده ایم بدلیل اینکه همانطور که قبول گفتیم یک کاربر می تواند چندین فاکتور داشته باشد
تمام کاری که اکنون باید انجام دهیم این است که به مدل فاکتور اطلاع دهیم که به یک مدل کاربر تعلق دارد. بیایید معکوس رابطه یک به چند را تعریف کنیم.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Invoice extends Model { public function user() { return $this->belongsTo(App\User::class); } }
آخرین نوع رابطه، رابطه چند به چند است. این نوع رابطه به این معنی است که یک مدل از نوع A ممکن است به چندین مدل از نوع B مرتبط شود و بالعکس.
به عنوان مثال ، رابطه بین مدل فاکتور و مدل محصول یک رابطه چند به چند است. یک فاکتور می تواند چندین محصول داشته باشد و یک محصول می تواند روی چندین فاکتور باشد.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Invoice extends Model { public function products() { return $this->belongsToMany(App\Product::class); } }
و معکوس این رابطه را می توانید اینگونه تعریف کنید:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Product extends Model { public function invoices() { return $this->belongsToMany(App\Invoice::class); } }
پیاده سازی روابط چند به چند (Many to many) کمی دشوارتر است زیرا به یک جدول اتصال در پایگاه داده نیاز دارد. با ایجاد یک فایل Migration می توانید این جدول اتصال را در Laravel ایجاد کنید.
این نوع رابطه مدل ها را از طریق یک رابط واسط لینک میکند. شرایطی را تصور کنید که هر محصول دارای یک تأمین کننده است و هر محصول دارای یک سابقه محصول است. سپس مدل تأمین کننده می تواند از طریق محصول به سابقه محصول دسترسی پیدا کند.
جدول های پایگاه داده به این شکل هستند:
suppliers: - id
products: - id - supplier_id
product_history: - id - product_id
حتی اگر جدول product_history دارای ستون supplier_id نباشد ، اما تأمین کننده (suppliders) می تواند با استفاده از رابطه "Has One Through" به اطلاعات product_history دسترسی پیدا کند.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Supplier extends Model { public function productHistory() { return $this->hasOneThrough(App\History::class, App\Product::class); } }
اولین آرگومان که به متد hasOneThrough پاس داده می شود نام مدل نهایی است. دومین آرگومان نام مدل میانی است.
رابطه "has many through" مشابه رابطه "has one through" است ، اما برای چندین رکورد. بیایید از مثال قبلی استفاده کنیم ، اما نیاز هست ما یک چیز را تغییر دهیم: یک محصول اکنون می تواند به جای یک مورد ، چندین سابقه مصحول داشته باشد. جداول پایگاه داده ثابت می مانند و تغییری نمیکنند.
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Supplier extends Model { public function productHistory() { return $this->hasManyThrough(App\History::class, App\Product::class); } }
به این ترتیب مدل تأمین کننده (supplier) می تواند به سابقه های محصول دسترسی پیدا کند.