之前介紹過 Laravel 的一對一關係 hasOne 跟 belongsTo (這裡),這次要進一步介紹 Laravel Eloquent 用來處理一對多關係的方法:hasMany 跟 belongsTo 。
-
hasMany指的是「擁有很多東西」。我擁有很多東西,並且我在它們的身上貼上了我的識別代碼。 -
belongsTo指的是「屬於某個人」。我屬於別人,我被貼上了他的識別代碼。
你沒看錯,belongsTo 重複出現了,至於為什麼,就請接著看下去吧!
範例
我們來看下面的範例,跟之前一樣,假設我們有兩張 Table,分別是 users 及 cars ,在 Laravel 中,分別會對應到 User 及 Car 兩個 Model。
這次跟一對一不一樣的是,我們設定,每個人可以擁有多輛車,每輛車只能被一個人擁有。
也就是一個人對到多台車,一對多關係。
我們將這樣的關係寫成實際的 Laravel 程式,首先是 User Model。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function cars()
{
return $this->hasMany(Car::class);
}
}
在 User Model中,cars method 使用 hasMany:
$this->hasMany(Car::class)
$this 在這邊指的是 User 物件 ,因此這行程式直接讀起來就是:User has many car(s),使用者擁有多輛車,應該還蠻直觀的吧!
再來看 Car Model :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Car extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
user method 使用 belongsTo :
$this->belongsTo(User::class)
這邊的 $this 就是 Car 物件,整句直接讀是: Car belongs to (a) user,車子屬於一個使用者。
詳細說明
回過頭來確認一次定義:
-
hasMany指的是「擁有很多東西」。我擁有很多東西,並且我在它們的身上貼上了我的識別代碼。 -
belongsTo指的是「屬於某個人」。我屬於別人,我被貼上了他的識別代碼。
複習一下,在資料庫中,兩張資料表間的關係,是透過外鍵(foreign key, FK) 來建立的,擁有外鍵的資料表,就像是被貼上了別人的識別代碼,而這個識別代碼通常是所屬者的 primary key, PK 。
為了說明方便,我將擁有 FK 的表稱為子表,相對的,把 PK 放在別人的 FK 中的則是母表。
hasMany
在一對一關係中,母表的 PK 頂多只會出現在子表中一次,不會出現多次,利用這樣的特性來做到一對一關係,這個時候母表的 Model 就可以透過 hasOne 來取出那個唯一一筆。
但在一對多關係中,母表的一個 PK 可以出現在子表中的多筆資料,代表這麼多筆資料都可以對應回同一筆母表資料。這個時候母表的 Model 就可以用 hasMany 來找出子表中的所有的筆數。
belongsTo
前面提過,belongsTo 在一對一關係,及一對多關係的反向關係都重複出現了,其實也很合理,因為一對一的反向,是對回一筆,一對多的反向,也是對回一筆:
- 一個人有一台車,反之,一台車只會對應一個主人。
- 一個人有多台車,反之,一台車只會對應一個主人。
因此不論在一對一或一對多關係中,要對應回母表,都可以透過 belongsTo 來對應回去,行為是一樣的。
結論
hasMany 跟 belongsTo 其實不太容易搞混。比較常令人困惑的是為什麼多對一跟一對一的反向關係,都是用 belongsTo 。但其實只要稍微想一下就清楚,其實都是反向對回一筆資料,所以都符合 belongsTo 的行為,這篇就先到這邊啦!謝謝各位閱讀。
本篇為 PHP 及 Laravel 系列文 → 看更多 PHP 及 Laravel 文章