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
の連想配列ですが、下記のように設定しています。
・`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つのデータが入っていることが確認できました。
作成したFruitFactoryのdefinition
メソッドに定義した通りにランダムな内容が登録されました。
今回はFactoryを使用するためにSeederに処理を書きました。
同じようにモデルからfactory
メソッドを使用することで、コントローラーの中で使用するなど任意の場所で使うことができます。
コメント