LaravelでFactoryを使ってテストデータを作成する方法!

Laravel Laravel

LaravelでFactoryを使って、Seederでテストデータを作成する方法を書いています。

前回はSeederを使って、テーブルにModelで初期データを入力するということをしました。(こちらの記事です)
Factoryを使用すると、Modelを使ってデータを作成するよりも簡単に大量なデータを入れることが可能です。

サンプルコードの検証にはLaravel8を使用しています。
Factoryの使用方法がLaravel8から変わったようなので、それ以前のバージョンの方は注意してください。
Factoryについての公式ドキュメントはこちらです。

Factoryを作成する

まず、FactoryをLaravelのartisanコマンドから作成します。
そして、ランダムなデータがインサートできるように作成したファイルを編集します。

Factoryで使用するモデルは前回と同じ、Fruitモデルを使用します。

カラム名 内容
id bigint テーブルのID
name varchar(255) フルーツの名前
color varchar(255) フルーツの色
price int 値段

artisanコマンドからFactoryを作成する

artisanコマンドを使用して、Factoryを作成します。
下記のようにmake:factoryの後に、モデルの名前を入力します。

php artisan make:factory Fruit

実行すると、下記のように表示されて、database/factories配下にFactoryファイルが作成されます。
今回はFruitモデルを指定したので、FruitFactory.phpなります。

php artisan make:factory Fruit  
Factory created successfully.

作成したファイルを確認すると、下記のように出力されました。

<?php

namespace Database\Factories;

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

class FruitFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Fruit::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            //
        ];
    }
}

artisanコマンド実行時にFruitを指定したので、$model変数にモデルのFruitクラスが指定されています。
これで、ModelとFactoryが関連付いて処理されます。

モデルの方にも必要な記載があります。
HasFactoryトレイトを使うようにしておく必要があります。
今回のFruitモデルは下記のように記載しています。

<?php

namespace App\Models;

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

class Fruit extends Model
{
    use HasFactory;
    protected $fillable = ['name', 'color', 'price'];
}

次項で、definitionメソッドに実際にデータを登録するカラムと値を記載します。

Factoryのdefinitionメソッドを修正する

definitionメソッドを修正して、登録するカラムと値を書いてみました。

<?php

namespace Database\Factories;

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

class FruitFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Fruit::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        $names = ['apple', 'banana', 'lemon', 'grape', 'orange', 'peach', 'pineapple'];
        $colors = ['red', 'yellow', 'purple', 'orange', 'pink', 'black', 'white'];

        $name = $names[rand(0, count($names) - 1)];
        $color = $colors[rand(0, count($colors) - 1)];
        return [
            'name' => $name,
            'color' => $color,
            'price' => rand(100,1500),
        ];
    }
}

returnする連想配列の左側のキーがカラム名になり、右側が値になります。

ランダムな内容が設定されるようにしてみました。
$names$colorsには適当な果物名と色の配列を作成しました。
このdefinitionメソッドが呼ばれるたびに、それぞれの配列からひとつだけ取得して、$name$colorに設定します。

$name = $names[rand(0, count($names) - 1)];
$color = $colors[rand(0, count($colors) - 1)];

rand関数を使って、0から要素数までのランダムなひとつの要素を配列から抜き出しています。

returnの連想配列ですが、下記のように設定しています。

・`name`カラムに取得したランダムな果物名
・`colors`カラムに取得したランダムな色
・`price`カラムに100から1500までのランダムな数値

これでFactoryでインサートする内容の設定が完了です。
この状態になれば、モデルからfactoryメソッドを使ってデータを作ることが可能です。

SeederでFactoryを使用する

作成したFactoryを使用するように、database/seeders/DatabaseSeeder.phpに記載します。

<?php

namespace Database\Seeders;

use App\Models\Fruit;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        Fruit::factory()->count(5)->create();
    }
}

これで、FruitモデルのFactoryが使用されてデータが作成されます。

Fruit::factory()でFruitモデルのFactoryを使うという意味になります。(作成したFactoryクラスです)
countメソッドは作成するデータ数を渡します。今回は5を渡しています。
そして、createメソッドを呼ぶことで、5つのランダムなfruitsテーブルのデータが作成されます。

Seederを実行して、Factoryで登録されるか確認する

Seederを実行して、実際にデータが登録されるか確認します。
下記コマンドでSeederが実行されます。database/seeders/DatabaseSeeder.phpファイルのrunメソッドが処理されます。

php artisan db:seed

実行すると、下記のように実行完了したことが確認できました。

php artisan db:seed
Database seeding completed successfully.

実行した後にテーブルを確認すると、ランダムな5つのデータが入っていることが確認できました。
LaravelのFactoryを使用したデータインサート

作成したFruitFactoryのdefinitionメソッドに定義した通りにランダムな内容が登録されました。

今回はFactoryを使用するためにSeederに処理を書きました。
同じようにモデルからfactoryメソッドを使用することで、コントローラーの中で使用するなど任意の場所で使うことができます。

コメント

タイトルとURLをコピーしました