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',
        ];
    });
}