Laravel 编码技巧 - Factories

作者: 温新

图书: 【Laravel 编码技巧】

阅读: 149

时间: 2024-02-29 19:33:58

工厂回调

在使用工厂为数据填充创建数据时,你可以提供工厂回调函数,在记录插入后执行某些操作。

$factory->afterCreating(App\User::class, function ($user, $faker) {
    $user->accounts()->save(factory(App\Account::class)->make());
});

生成带图像的数据工厂或填充

你知道吗,Faker 不仅可以生成文本值,还可以生成图像。请看下面的示例 - 这将生成一个 50x50 的图像:

$factory->define(User::class, function (Faker $faker) {
    return [
        'name'              => $faker->name,
        'email'             => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password'          => bcrypt('password'),
        'remember_token'    => Str::random(10),
        'avatar'            => $faker->image(storage_path('images'), 50, 50)
    ];
});

使用自定义逻辑覆盖值

在使用工厂创建记录时,你可以使用 Sequence 类来覆盖某些值并对其应用自定义逻辑。

$users = User::factory()
    ->count(10)
    ->state(new Sequence(
        ['admin' => 'Y'],
        ['admin' => 'N'],
    ))
    ->create();

使用具有关系的工厂

在使用具有关联关系的工厂时,Laravel 还提供了一些魔术方法。

// 使用魔术工厂关联方法
User::factory()->hasPosts(3)->create();

// 相当于
User::factory()->has(Post::factory()->count(3))->create();

创建模型而不分派任何事件

有时,您可能希望更新给定的模型而不触发任何事件。你可以使用 updateQuietly 方法来实现这一点。

Post::factory()->createOneQuietly();

Post::factory()->count(3)->createQuietly();

Post::factory()->createManyQuietly([
    ['message' => 'A new comment'],
    ['message' => 'Another new comment'],
]);

在上述示例中,createOneQuietlycreateQuietlycreateManyQuietly 方法用于创建模型实例,但不会触发与创建相关联的事件。这对于在不需要触发事件的情况下进行模型创建操作非常有用。

有用的 for 方法

Laravel 工厂有一个非常有用的 for() 方法,您可以使用它来创建 belongsTo() 关联。

public function run()
{
    Product::factory()
        ->count(3)
        ->for(Category::factory()->create())
        ->create();
}

在上述示例中,for() 方法用于创建 Product 模型实例,每个模型都与一个通过 Category::factory()->create() 创建的类别相关联。这使得创建具有 belongsTo 关系的记录变得简单而直观。

运行工厂而不调度事件

如果想在不触发任何事件的情况下使用 Factory 创建多条记录,可以将代码封装在 withoutEvents 闭包中。

$posts = Post::withoutEvents(function () {
    return Post::factory()->count(50)->create();
});

在 run() 方法中指定依赖项

你可以在 seeder 的 run() 方法中指定依赖项。

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $user = User::factory()->create();

        $this->callWith(EventSeeder::class, [
            'user' => $user
        ]);
    }
}
class EventSeeder extends Seeder
{
    public function run(User $user)
    {
        Event::factory()
            ->when($user, fn($f) => $f->for('user'))
            ->for(Program::factory())
            ->create();
    }
}
请登录后再评论