Laravel 學習筆記 — Model 關連性/一對一/一對多 (1)

ViNciHsu
5 min readOct 14, 2020

--

此篇主要假設一家數店只能賣一本書,從中了解商店跟書 (一對一)的關聯性

Store vs. Book

php artisan make:model Store -m // m表示順便建出migration

將剛才產生的資料表結構進行一點修改,此處加上 title 欄位

migration 中,自己增加 title 這個欄位

接著執行 php artisan migrate ,到 SQLite 確認新的資料表 store 其結構是否如所建,多了 title 這個欄位

SQLite 中確認 store 資料表結構有多了 title

接下來到 App\Models\Store.php 中,加個 function ,使其一對一

建立一對一關聯性,並允許 title 欄位能大量新增

**在過程中,如果出現以下紅色錯誤:

PHP Fatal error: Class ‘Store’ not found in Psy Shell code on line 1

可以試著使用 composer dump-autoload 清除緩存,此處測試有效

清除緩存後,再次新增即可

清除緩存後,再次新增即可

但是,到目前為止,還未做完,如果 $s1->book 會出現以下錯誤,代表剛才在中,加了 book() 這個 function 就有效果了

還必須要在 Book 中有所對應,即:

Store

- hasOne

Book (Book必須要和 Store 有所對應,要加個欄位小寫 store+id = store_id)

- store_id

在終端機執行 php artisan make:migration add_store_id_to_books

加上 store_id 這個欄位,並且加上 nullable() ,代表此欄可以是空的

執行 php artisan migrate 後,查看 SQLite 中 books 資料表是否新增了 store_id 欄位

books 資料表新增了 store_id 欄位

接下來我們到 tinker 查看如何關聯,取得 Store 的第一筆,及 Book 的第一筆

Store 的第一筆
Book 的第一筆

將其關聯 $s1->book()->save($b1)

一對一的關聯建立了

SQLite 中可以看到 books 資料表中 store_id 欄位已寫入了 stores 資料表中 id 為 1 的關聯

SQLite 中可以看到 books 資料表中 store_id 欄位已寫入了 stores 資料表中 id 為 1 的關聯

接下來就能使用 tinker 查詢 Store 中,唯一對應到的那本書書名

$s = Store::first()

$s->book

$s->book->title

查詢到 Store 一對一中對應到的書名 title

正向查詢可以,那麼反向查詢是否也可以呢?

會發現反向用書去找是哪個書店找不到

查不到的原因在於,剛才在 Model 中只有寫了正向的 function book() ,並沒有針對反向的 Store 寫相關聯的 function

在 Book.php 中加上關聯的 function store()

重新操作一次,即可反向查詢該書屬於哪間商店,其商店名稱為何

當有設定了 hasOne() 以及 belongsTo() 後,我們就能從正向查詢關聯,也能從反向查回來;那麼是否一定要雙向都設定呢?其實不需要,belongsTo() 的設定可以在有此查詢需求時再設定就好。

--

--

No responses yet