Laravel8 シーダー、モデルファクトリー 配列から属性を上書きしてテストデータを作成する

## はじめに

Laravel8のシーダー、モデルファクトリーで配列を使って属性を上書きしてテストデータを作成するtipsです。

## 環境

- PHP8.0.1
- Laravel 8.23.1

## 準備

下記のモデル、モデルファクトリーがあると仮定してシーダーを作成します。

### マイグレーション

```php:database/migrations/1970_01_01_000001_create_companies_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCompaniesTable extends Migration
{
    public function up()
    {
        Schema::create('companies', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->integer('capital');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('companies');
    }
}
```

### モデル

```php:app/Models/Company.php
<?php declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Company extends Model
{
    use HasFactory;

    protected $guarded = [
        'id',
        'created_at',
        'updated_at',
    ];

    protected $casts = [
        'name' => 'string',
        'capital' => 'int',
    ];
}
```

### モデルファクトリー

```php:database/factories/CompanyFactory.php
<?php declare(strict_types=1);

namespace Database\Factories;

use App\Models\Company;
use Illuminate\Database\Eloquent\Factories\Factory;

class CompanyFactory extends Factory
{
    protected $model = Company::class;

    public function definition()
    {
        return [
            'name' => $this->faker->company,
            'capital' => (int) round($this->faker->numberBetween(1000, 10000), -2),
        ];
    }
}
```

## シーダー

```php:database/seeders/CompaniesTableSeeder.php
<?php declare(strict_types=1);

namespace Database\Seeders;

use App\Models\Company;
use Illuminate\Database\Eloquent\Factories\Sequence;
use Illuminate\Database\Seeder;

class CompaniesTableSeeder extends Seeder
{
    public function run()
    {
        // 全件削除
        Company::truncate();

        // 1件データを作る
        Company::factory()->create();

        // 5件データを作る
        Company::factory(5)->create();

        // 5件データを作る(countでも良い)
        Company::factory()->count(5)->create();

        // capital(資本金)が5000のデータ5件を作る
        Company::factory(5)->create(['capital' => 5000]);

        // name(会社名)を指定したデータ5件を作る
        $companies = [
            ['name' => '株式会社A'],
            ['name' => '株式会社B'],
            ['name' => '株式会社C'],
            ['name' => '株式会社D'],
            ['name' => '株式会社E'],
        ];
        Company::factory(count($companies))
            ->state(new Sequence(...$companies))
            ->create();

        // capital(資本金)が1000,5000を交互に入れるデータ5件を作る
        Company::factory(count($companies))
            ->state(new Sequence(
                ['capital' => 1000],
                ['capital' => 5000]
            ))
            ->create();
    }
}
```

## DBの中身

上記のシーダーを実行するとこのようなデータが作成されます。

![ScreenShot 2021-01-26 9.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/113a5c3a-02e2-6243-7461-bb7107d82bae.png)

連続したデータを作る場合は `Illuminate\Database\Eloquent\Factories\Sequence` を使うと綺麗に書けます。
ぜひ使っていきましょう！

## 関連記事

- [Laravel8で完成されたModelFactoryの使い方](https://qiita.com/ucan-lab/items/788d1a603f2b53ebb999)

## 参考

- [モデルファクトリの定義 | Laravel 8.x データベーステスト](https://readouble.com/laravel/8.x/ja/database-testing.html#defining-model-factories)