什么是工厂
在测试和数据库填充中,往往需要向数据库插入记录。 比起手动指定每一列的值,使用 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() 方法,用来定义默认属性。
工厂状态(States)
通过 state 方法可以为工厂定义单独的属性变化。软删除 state
对启用了软删除的模型,可以使用内置的trashed() state。
工厂回调(Callbacks)
通过afterMaking 和 afterCreating 可以定义模型生成后的附加处理。
生成模型
make() — 不保存到数据库
create() — 保存到数据库
覆盖属性
给make() 或 create() 传入数组,可以只覆盖特定属性。
用工厂生成模型时,批量赋值保护会被自动禁用。
Sequence(序列)
在批量生成模型时,如果希望按顺序切换属性,可以使用Sequence。
sequence() 方法可以写得更简洁。
关联关系的工厂
Has Many(一对多)
使用has() 方法生成带“一对多”关联的模型。
has + 关联名的复数)可以写得更简洁。
Belongs To(反向关联)
使用for() 方法指定所“属于”的父模型。
Many to Many(多对多)
使用hasAttached() 方法处理多对多关联,还可以指定中间表的属性。
多态关联
普通“一对多”一样,可以使用has() 或魔术方法。
morphTo 关联,不能使用魔术方法。需要在 for() 中明确指定关联名。
工厂内定义关联
在definition() 中把另一个工厂赋值给外键,就能在生成模型时自动创建父模型。
recycle() — 复用已有模型
如果多个关联想复用同一个模型实例,可以使用recycle()。
在数据填充中使用
可以在DatabaseSeeder 或其他 Seeder 类中调用工厂。
在测试中使用
测试时通常将RefreshDatabase trait 与工厂搭配使用。
RefreshDatabase 会在每个测试之间重置数据库,因此测试之间的数据不会相互干扰。
下一步
数据库填充
查看如何组合 Seeder 与工厂来注入初始数据。
测试入门
了解 Laravel 的测试功能以及 RefreshDatabase trait 的使用方式。