在我的博客应用中,每个篇博客文章都属于某一个专栏,在显示文章列表之前,先为专栏填充一些数据。

填充文件

Laravel 内置了一个可为你的数据库填充测试数据的填充类。所有的填充类都放在 database/seeds 目录下。Laravel 默认定义了一个 DatabaseSeeder 类。通过这个类,你可以用 call 方法来运行其他的 seed类,从而控制数据填充的顺序。

运行 artisan 命令 make:seeder 可以生成 Seeder,框架生成的seeders 都放在 database/seeders 目录下:

  1. php artisan make:seeder ColumnSeeder

打开生成的 ColumnsSeeder文件,看看默认代码:

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ColumnsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}

Seeder 类只包含一个默认方法:run。这个方法会在执行 db:seed 这个 Artisan command命令时被调用。在run方法里,可以按需在数据库中插入数据。

模型工厂

手动为每个模型填充指定属性很麻烦,在 Laravel 中可以使用模型工厂轻松地生成大量数据库数据。

移除默认工厂

Laravel 项目的工厂文件默认存放在 database/factories目录下,Laravel 项目默认生成了 UserFactory.php文件,如前面所说一样,在这个博客项目中用不到,可以移除掉:

rm database/factories/UserFactory.php

添加工厂文件

运行如下命令添加数据工厂:

php artisan make:factory ColumnFactory

打开生成的 ColumnFactory工厂文件,可以看到默认代码如下:

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Column>
 */
class ColumnFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            //
        ];
    }
}

定义工厂后,可以在模型中使用 Illuminate\Database\Eloquent\Factories\HasFactory 特性提供的 factory 静态方法,来为模型实例化工厂。

HasFactory 特性的 factory 方法将按约定来为模型确定合适的工厂。具体来说,该方法将在 Database\Factorys 的命名空间下查找类名与模型名相匹配,并以 Factory 为后缀的工厂。

修改 ColumnFactory

修改 ColumnFactory.php文件,文件内容如下:
database/factories/ColumnFactory.php

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Column>
 */
class ColumnFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'name' => $this->faker->sentence()
        ];
    }
}

Faker 是一个假数据生成库,sentence()faker 提供的 API ,随机生成『小段落』文本。我们用来填充 name 专栏名称字段。

修改 ColumsSeeder

修改 ColumnFactory.php文件,文件内容如下:
database/seeders/ColumnSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Column;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ColumnsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Column::factory()->count(10)->create();
    }
}

User::factory() 是模型方法,当我们在模型里使用 trait HasFactory 时会注入此方法。返回的是模型工厂类实例,对应加载 ColumnFactory.php 类。

count(5)指定生成模型的数量,此处生成 10 个专栏数据。

注册数据填充

接下来注册数据填充:
databases/seeders/DatabaseSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(ColumnsSeeder::class);
    }
}

执行数据填充

运行如下命令执行数据填充:

php artisan db:seed

执行完成后就可以看到columns 数据表增加了 10 条数据。
image.png