什麼是關聯
資料庫的資料表之間常有關聯關係。例如,一篇部落格文章可能有多則評論,或訂單會與下單的使用者相關聯。 Eloquent 為這些資料表間的關聯提供了簡單的定義與操作方式。關聯是定義為 Eloquent 模型上的方法。本頁使用
User、Post、Comment、Tag 等具體模型作為範例。
假設這些模型與資料表已建立好。hasOne(一對一)
hasOne 代表某模型只擁有另一個模型的一筆。例如 User 擁有一個 Profile。
定義關聯
在User 模型中定義 profile 方法。
profiles 資料表有 user_id 欄位。
取得關聯資料
已定義的關聯可以以屬性方式存取。belongsTo(一對一反向)
belongsTo 是 hasOne 的反向,定義在擁有外鍵一側的模型。表達 Profile 屬於 User 的關係。
定義關聯
_id(此例中 user_id)作為外鍵。
取得關聯資料
hasMany(一對多)
hasMany 是最常使用的關聯,代表一個父模型擁有多個子模型。例如 Post 有多個 Comment。
定義關聯
comments 資料表有 post_id 欄位。
取得關聯資料
hasMany 關聯會回傳集合。
反向關聯(belongsTo)
要從評論參照文章,可在Comment 模型中定義 belongsTo。
belongsToMany(多對多)
多對多關聯用於兩方模型互相擁有多個關聯的情境。例如Post 有多個 Tag,而 Tag 也屬於多個 Post。
資料表結構
多對多需要中介資料表。Post 與 Tag 的例子中會準備一張叫做 post_tag 的中介資料表。
中介資料表名稱由 Eloquent 依關聯的兩個模型名稱按字母順序合併推測(
post + tag → post_tag)。定義關聯
Tag 這邊也定義同樣的方法,就能從反方向也存取。
取得關聯資料
新增 / 移除關聯資料
以attach 新增中介資料表紀錄,detach 刪除。
Eager Loading
什麼是 N+1 問題
以屬性方式存取關聯時,Eloquent 會每次都執行查詢。這稱為「延遲載入(Lazy Loading)」。在迴圈中存取關聯會發生 N+1 問題。用 with() 進行 Eager Loading
透過with() 方法可以一起取得關聯資料,將查詢降到 2 次。
一次 Eager Load 多個關聯
可用陣列指定多個關聯。巢狀的 Eager Loading
以點記號可 Eager Load 巢狀關聯。下一步
Eloquent 入門
回頭複習 Eloquent 的基本 CRUD 操作。