Eloquent:数据工厂
介绍
当测试你的应用程序或向数据库填充数据时,你可能需要插入一些记录到数据库中。Laravel 允许你使用模型工厂为每个 Eloquent 模型定义一组默认属性,而不是手动指定每个列 的值。
要查看如何编写工厂的示例,请查看你的应用程序中的 database/factories/UserFactory.php
文件。这个工厂已经包含在所有新的 Laravel 应用程序中,并包含以下工厂定义:
namespace Database\Factories;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserFactory extends Factory
{
/**
* 定义模型的默认状态
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
}
正如你所见,在其最基本的形式下,数据工厂是扩展 Laravel 基础工厂类并定义一个 definition
方法的类。definition
方法返回在使用工厂创建模型时应用的默认属性值集合。
通过 fake
辅助器,工厂可以访问 Faker PHP 库,它允许你方便地生成各种用于测试和填充的随机数据。
你可以通过在 config/app.php
配置文件中添加 faker_locale
选项来设置你应用程序的 Faker 区域设置。
定义模型工厂
创建工厂
要创建工厂,请执行 make:factory
Artisan 命令:
php artisan make:factory PostFactory
新工厂类将被放置在你的 database/factories
目录中。
模型和工厂的自动发现机制
一旦你定义了工厂,你可以使用 Illuminate\Database\Eloquent\Factories\HasFactory
特征提供给模型的静态 factory
方法来为该模型实例化工厂。
HasFactory
特征的 factory
方法将使用约定来确定适用于特定模型的工厂。具体而言,该方法将在 Database\Factories
命名空间中查找一个工厂,该工厂的类名与模型名称匹配,并以 Factory
为后缀。如果这些约定不适用于你的特定应用程序或工厂,则可以在模型上覆盖 newFactory
方法,以直接返回模型对应的工厂的实例:
use Illuminate\Database\Eloquent\Factories\Factory;
use Database\Factories\Administration\FlightFactory;
/**
* 为模型创建一个新的工厂实例。
*/
protected static function newFactory(): Factory
{
return FlightFactory::new();
}
接下来,定义相应工厂的 model
属性:
use App\Administration\Flight;
use Illuminate\Database\Eloquent\Factories\Factory;
class FlightFactory extends Factory
{
/**
* 工厂对应的模型名称。
*
* @var string
*/
protected $model = Flight::class;
}
工厂状态
状态操作方法可以让你定义离散的修改,这些修改可以在任意组合中应用于你的模型工厂。例如,你的 Database\Factories\UserFactory
工厂可能包含一个 suspended
状态方法,该方法可以修改其默认属性值之一。
状态转换方法通常会调用 Laravel 基础工厂类提供的 state
方法。state
方法接受一个闭包函数,该函数将接收为工厂定义的原始属性数组,并应返回一个要修改的属性数组:
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* 表示用户已被暂停。
*/
public function suspended(): Factory
{
return $this->state(function (array $attributes) {
return [
'account_status' => 'suspended',
];
});
}