昨天是多對多的上篇,今天會接續昨天的內容,繼續看多對多在Laravel中的關係,在migration之後,再接著看多對多關聯表在Model和Controller中的實作,讓我們開始愉悅的第20天吧!
資料表建立好後,接著要為兩個外來鍵找到該去的地方,想到關聯就需要想到Model,進入joiner的model,你以為我會這麼說嗎?不,在關係中,joiner始終是局外人,在暑假寫Laravel的時候,經常誤會Model的職責,Model只記錄關係,我們過去經常使用的user() -> articles()
是去article的table找這位使用者有關的文章,->
後更像作用是找東西的function,所以我們想要建立article和user的關係,互相從身上找到對方的痕跡,joiner只是作為中間表的存在,所以我們先進入app\Models\Article.php
,
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
...
public function joinArticles(): BelongsToMany
{
return $this->belongsToMany(Article::class, 'joiners', 'user_id', 'article_id') -> withPivot('phone', 'birthday', 'ID_number', 'note')->withTimestamps();
}
首先與一對一和一對多都不一樣的點,在多對多的關系是對稱的BelongsToMany,接著看向return的結果,是個參數分別是關聯的表、中間表的名稱和中間表的外來鍵先放位在的表,再放關聯的表,對應user和article,在user的Model就先放user_id再放article_id。
除了關聯的表必填之外,如果不自定義中間表的名稱,Laravel預設是照兩個表的英文字母排序,例如:article_user或role_user,後面的外來鍵也是可以自訂義的,但需考慮清楚是否有自訂義的必要再做修改,避免未來認不出自己的孩子。
withPivot,是我們中間表的屬性,如果在使用這個關係時,需要接觸中間表的值,都要先放進這裡的withPivot,所以我們把屬性一一放進去,而pivot的使用在未來也是值得注意的點,我們就親身跳過許多坑,之後使用到時會在近一步介紹。
最後的withTimestamps,如果需要時間戳記錄可以放上。
同理我們需要反向查詢,我們也需要去一趟article的Model裡,
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
...
public function joiners(): BelongsToMany
{
return $this->belongsToMany(User::class, 'joiners') -> withPivot('phone', 'birthday', 'ID_number', 'note')->withTimestamps();
}
在user和article之後,我們仍需要去一趟joiner,不是為了關係,因為我們需要儲存資料,我們要放上fillable,進入app\Models\Joiner.php
,
use Illuminate\Database\Eloquent\Relations\Pivot;
class Joiner extends Pivot
{
use HasFactory;
protected $fillable = [
'note',
'phone',
'birtherday',
'ID_number'
];
}
特別是joiner之後的extends Pivot,有別於user和article的Model,在編寫程式碼的時候要特別注意。
總結一下今天的內容,我們認識了Model在多對多的關聯中,扮演了什麼角色,接續了19天多對多的migration,準備了這麼久,明天我們就會進入實作報名功能,實際上手操作我們的資料與關聯。