Skip to main content

什麼是工廠

在測試或資料庫 seeding 時,我們常需要在資料庫中插入紀錄。 與其手動指定每個欄位的值,你可以透過 Laravel 的模型工廠,為每個 Eloquent 模型定義一組預設屬性。 所有新的 Laravel 應用程式都會附上 database/factories/UserFactory.php
透過 fake() 輔助函式,可使用 Faker 函式庫生成各種隨機資料。
Faker 的 locale 可透過 config/app.phpfaker_locale 選項變更。

產生工廠

make:factory Artisan 指令建立工廠。
新工廠類別會被放到 database/factories 目錄。

模型與工廠的自動偵測

若模型使用 HasFactory trait,Laravel 會自動找到對應的工廠。 它會在 Database\Factories 命名空間中,尋找模型名稱後綴 Factory 的類別。 若命名規則不符,可用 UseFactory 屬性明確指定。

定義工廠

definition() 方法

工廠的核心方法 definition() 定義預設屬性。
Faker 常用方法一覽:

工廠狀態(States)

透過狀態方法可以為工廠定義個別變化。
狀態可以組合使用。

軟刪除的狀態

若模型支援軟刪除,可以使用內建的 trashed() 狀態。

工廠回呼(Callbacks)

可透過 afterMakingafterCreating 定義模型生成後的額外處理。
在狀態方法內也可以註冊回呼。

建立模型

make() — 不存入 DB

create() — 存入 DB

覆寫屬性

傳入陣列給 make()create(),即可只覆寫特定屬性。
也可以使用狀態進行 inline 覆寫。
工廠建立模型時,會自動停用 mass assignment 保護。

Sequence(序列)

若要在建立多個模型時輪流變換屬性,可使用 Sequence
透過 sequence() 方法可寫得更簡潔。
也可以用閉包動態生成隨機值。

關聯的工廠

Has Many(一對多)

透過 has() 方法建立擁有「一對多」關聯的模型。
使用魔法方法可以更精簡(has + 關聯名稱複數形式)。

Belongs To(反向關聯)

透過 for() 指定所屬的父模型。
魔法方法版本:

Many to Many(多對多)

透過 hasAttached() 方法處理多對多關聯,也可指定中介資料表屬性。
魔法方法版本:

多型關聯

與一般的「一對多」相同,可用 has() 或魔法方法。
morphTo 關聯無法使用魔法方法,須以 for() 明確指定關聯名稱。

工廠內定義關聯

definition() 中將外鍵指派為另一個工廠,建立模型時會自動一起建立父模型。

recycle() — 重複利用既有模型

若要在多個關聯中重複利用同一個模型實例,可使用 recycle()

Seeding 中的使用

DatabaseSeeder 或 seeder 類別中呼叫工廠。
執行 seeder:

測試中的使用

在測試中可搭配 RefreshDatabase trait 使用工廠。
RefreshDatabase 會在每次測試前重置資料庫,讓不同測試間資料互不干擾。
在 Pest 中測試時,工廠 API 完全相同。 請使用 uses(RefreshDatabase::class) 重置資料庫。

下一步

資料庫 Seeding

瞭解如何結合 seeder 與工廠匯入初始資料。

測試入門

熟悉 Laravel 的測試功能與 RefreshDatabase trait 用法。
最後修改於 2026年8月2日