跳转到主要内容

什么是工厂

在测试和数据库填充中,往往需要向数据库插入记录。 比起手动指定每一列的值,使用 Laravel 的模型工厂可以为每个 Eloquent 模型定义一套默认属性。 每个新的 Laravel 应用都自带了 database/factories/UserFactory.php
通过 fake() 辅助函数可以使用 Faker 库,生成各种随机数据。
Faker 的语言环境可以通过 config/app.php 中的 faker_locale 选项修改。

生成工厂类

使用 make:factory Artisan 命令来创建工厂。
新的工厂类会被放到 database/factories 目录下。

模型与工厂的自动发现

在模型上使用 HasFactory trait 时,Laravel 会自动查找对应的工厂类。 它会在 Database\Factories 命名空间中查找 “模型名 + Factory” 的类名。 如果命名规则不匹配,可以使用 UseFactory 属性显式指定。

定义工厂

definition() 方法

工厂的核心是 definition() 方法,用来定义默认属性。
Faker 常用方法一览:

工厂状态(States)

通过 state 方法可以为工厂定义单独的属性变化。
state 可以组合使用。

软删除 state

对启用了软删除的模型,可以使用内置的 trashed() state。

工厂回调(Callbacks)

通过 afterMakingafterCreating 可以定义模型生成后的附加处理。
state 方法内也可以注册回调。

生成模型

make() — 不保存到数据库

create() — 保存到数据库

覆盖属性

make()create() 传入数组,可以只覆盖特定属性。
也可以通过 state 实现内联覆盖。
用工厂生成模型时,批量赋值保护会被自动禁用。

Sequence(序列)

在批量生成模型时,如果希望按顺序切换属性,可以使用 Sequence
使用 sequence() 方法可以写得更简洁。
也可以通过闭包动态生成随机值。

关联关系的工厂

Has Many(一对多)

使用 has() 方法生成带“一对多”关联的模型。
使用魔术方法(has + 关联名的复数)可以写得更简洁。

Belongs To(反向关联)

使用 for() 方法指定所“属于”的父模型。
魔术方法版本:

Many to Many(多对多)

使用 hasAttached() 方法处理多对多关联,还可以指定中间表的属性。
魔术方法版本:

多态关联

普通“一对多”一样,可以使用 has() 或魔术方法。
对于 morphTo 关联,不能使用魔术方法。需要在 for() 中明确指定关联名。

工厂内定义关联

definition() 中把另一个工厂赋值给外键,就能在生成模型时自动创建父模型。

recycle() — 复用已有模型

如果多个关联想复用同一个模型实例,可以使用 recycle()

在数据填充中使用

可以在 DatabaseSeeder 或其他 Seeder 类中调用工厂。
执行 Seeder:

在测试中使用

测试时通常将 RefreshDatabase trait 与工厂搭配使用。
RefreshDatabase 会在每个测试之间重置数据库,因此测试之间的数据不会相互干扰。
使用 Pest 编写测试时工厂 API 完全一样。 记得通过 uses(RefreshDatabase::class) 重置数据库。

下一步

数据库填充

查看如何组合 Seeder 与工厂来注入初始数据。

测试入门

了解 Laravel 的测试功能以及 RefreshDatabase trait 的使用方式。
最后修改于 2026年7月18日