Laravel101:播种机和工厂实用指南
#php #laravel #database #seed

在开发过程中,有时我们需要使用数据来评估系统的功能。在Laravel中,我们有两个称为播种机和工厂的有用工具,可以帮助我们生成随机数据。在本文中,我们将探索这些工具并学习如何有效使用它们。


Laravel中的工厂类就像工厂,为我们的数据库表生成随机数据。如果您导航到项目中的database/factories目录,则会找到一个名为UserFactory的课程:

class UserFactory extends Factory
{
    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),
        ];
    }
}

在每个工厂类中,都有一个称为definition的重要函数,它指定了应如何填写每个属性。为此,Laravel使用了一个称为fakerPHP的功能强大的包,该软件包可以生成随机数据,例如名称,句子,段落,甚至图像。您可以在以下链接中找到有关此软件包的辅助功能和功能的更多信息。

FakerPHP / Faker

Fakerphp / Faker的文档

favicon fakerphp.github.io

UserFactory类中的另一点是被视为固定密码的字符串是hashed Word“密码”。

laravel包括各种全球助手PHP功能,其中之一称为Str。该辅助功能可用于处理字符串,例如生成随机字符串。您可以在here上参考此辅助功能的文档。

现在,让我们回到我们的项目并为我们的标签生成工厂。要创建工厂,我们可以使用以下工匠命令:

php artisan make:factory TagFactory

通常建议在工厂课程中使用单数名称。但是,如果要在生成工厂时指定模型,则可以在命令中使用–m'选项,例如:

php artisan make:factory TagFactory -m Tag

在我们的标签模型中,我们只有一个简单的名称属性,可以定义如下:

use Illuminate\Database\Eloquent\Factories\HasFactory;

class Tag extends Model
{
    use HasFactory;
}

我们建立了工厂后,我们可以使用它来创建模型的实例。为此,只需在要创建模型实例时调用工厂方法。

您还可以控制要生成的随机数据条目的数量。您可以使用工厂功能或计数功能来实现这一目标。例如,如果要创建5个随机标签,则可以使用以下代码:

Tag::factory(5)->create();

此外,在生成数据时,可以定义具有所需值的特定属性。例如,如果您想创建5个用名称测试的用户,但是您不关心其他属性,则可以使用以下代码:

User::factory(5)->create(['name' => 'test']);

在我们的项目中,我们目前有两个为用户和标签模型的工厂。现在,我们需要为我们的任务模型创建另一个工厂。

定义工厂模型时,重要的是要考虑关系模型。在我们的任务模型中,每个任务都与用户关联。因此,我们要实现的是使用给定用户的ID创建一个随机任务。

但是,在测试您的应用程序时,可能在某些情况下在环境中没有创建用户。在这种情况下,生成随机用户可能是可行的解决方案。为此,您可以像Bellow一样再次使用工厂模型:

public function definition(): array
{
    return [
        "title" => fake()->sentence(),
        "description" => fake()->paragraph(),
        "expired_at" => fake()->dateTimeThisMonth(),
        "user_id" => User::factory(),
    ];
}

如果您在修补匠中运行代码,您会注意到已经为任务模型创建了新用户。

Image description

还可以选择在生成任务时指定user_id。但是,我建议对数据库中可能已经存在的用户进行重新分配:

public function definition(): array
{
    return [
        "title" => fake()->sentence(),
        "description" => fake()->paragraph(),
        "expired_at" => fake()->dateTimeThisMonth(),
        "user_id" => User::query()->inRandomOrder()->first()?->id ?? 
           User::factory(),
    ];
}

为了在Laravel中更有效地生成随机数据,我们比使用修补匠有更好的解决方案。它称为播种机。

database/seeders目录中,您会找到一个名为DatabaseSeeder的类,该类允许我们管理随机数据的生成。

让我们更新DatabaseSeeder类,如下所示,然后执行工匠命令以运行此功能。

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        Task::factory()->create();
    }
}

这是工匠播种的命令:

php artisan db:seed

是!

使用Seeder,我们可以在数据库中使用Artisan轻松创建随机任务记录。此外,我们具有为不同情况创建多个播种机的灵活性。要创建一个播种机,您只需要运行php artisan make:seed <seeder-name>命令。

现在,让我们创建一个生成5个随机任务记录的TaskSeeder,每个任务都与两个随机标签相关联:

namespace Database\Seeders;

use App\Models\Tag;
use App\Models\Task;
use Illuminate\Database\Seeder;

class TaskSeeder extends Seeder
{
    public function run(): void
    {
        Task::factory(5)->hasTags(2)->create();
    }
}

要运行此播种机,您可以通过指定所需的种子类来使用工匠命令。

php artisan db:seed TaskSeeder

或者您可以在DatabaseSeeder中使用呼叫方法执行您的种子类:

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $this->call(TaskSeeder::class);
    }
}

初始数据模型

好吧,有时需要初始化某些值,例如文章的状态(例如,已发布或草稿)或交易状态(例如,付费或无付款)。

我想在此项目中应用类似的方法。我们有几个选择来实现这一目标。

一个选项是将初始值存储在配置文件中。为此,我们可以在指定的配置路径上创建一个名为“默认值”的PHP文件,并在此处定义所需值:

<?php

return [
    'tags' => ['php', 'laravel', 'develop', 'backend']
];

我们可以使用迁移文件初始化这些值。

另外,我们可以使用播种机初始化这些值。这意味着我们将定义像TagSeeder这样的播种机,该播种机填充数据库中的默认值。

两种方法都可以使用,但我更喜欢使用播种机,因为它更清楚:

让我们定义TagSeeder并初始化其值:

class TagSeeder extends Seeder
{
    public function run(): void
    {
        foreach (config('defaults.tags') as $value) {
            Tag::firstOrCreate(['name' => $value]);
        }
    }
}

您可以看到,Laravel中的辅助函数配置用于从配置文件中检索静态信息。

在这里,我使用firstOrCreate方法,该方法仅在没有添加时添加新的标签记录。

太好了!现在,让所有人聚集在一起,努力实施一个场景,如下所述的TaskSeeder中所述的场景:

namespace Database\Seeders;

use App\Models\Tag;
use App\Models\Task;
use App\Models\User;
use Illuminate\Database\Seeder;

class TaskSeeder extends Seeder
{
    public function run(): void
    {
        // create a user with specified credentials
        $user = User::factory()->create(['email' => 'test@test.dev']);

        // init tag with defined value
        $this->call(TagSeeder::class);

        // create 5 random tasks for the user
        $tasks = Task::factory(5)->create(['user_id' => $user->id]);

        // assosiate each generated tasks with 2 predefined tags
        foreach ($tasks as $task) {
            $tags = Tag::query()->inRandomOrder()->take(2)->pluck('id');
            $task->tags()->attach($tags);
        }
    }
}

现在让我们重建我们的数据库,并用这个定义的播种机填充它。要重建数据库,您可以运行migrate:fresh手工命令,该命令将丢弃所有表并重新运行所有迁移:

Image description

,如果您使用用户登录,您会看到成功生成的任务:

Image description


我希望这种解释阐明了在拉拉维尔(Laravel)中使用播种机和工厂的过程。如果您还有其他问题,请随时提出!