はじめに
laravelではテスト時など決まったデータなどが欲しい場合に自動で投入してくれるFactoryという機能がある。
今回はそのFactoryの基本的な使い方のおさらいと少し拡張した便利な使い方を書いていく。
Factoryファイルを作成する
$ php artisan make:factory Test
こんな感じで出ればOK
INFO Factory [database/factories/TestFactory.php] created successfully.
作られたファイルを以下のような感じで書いていく
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class UserFactory extends Factory
{
/**
* モデルのデフォルト状態の定義
*
* @return array
*/
public function definition()
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
}
一番基本的な形式では、ファクトリはLaravelの基本ファクトリクラスを拡張し、definitionメソッドを定義するクラスです。
definitionメソッドは、ファクトリを使用してモデルを作成するときに適用する必要がある属性値のデフォルトセットを返します。
上記は公式ページからの引用だが、
原則definition
メソッドの中にFactoryの処理を書いていく。
そうすることで、別のファイルからTest::factory()->create()
などのコマンドが打たれたときに該当の箇所が呼び出される。
※以下でまたまとめる
FactoryとModelの対応付けをする
Factory生成後はIlluminate\Database\Eloquent\Factories\HasFactoryトレイトを対象となるモデルクラスに読み込んであげる
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Test extends Model
{
use HasFactory;
Factory側にも以下のような感じで書いてあげる。(マストではないのかな?)
class TestFactory
{
protected $model = Test::class;
//
}
Factoryの呼び出し方
テストファイルやシーダーファイルに書いてあげることが多いが、
基本的に下記のように書いてあげる。
$test = Test::factory()->create(); // DBに追加する
複数作成する場合は
$test = Test::factory(2)->create();
などとしてあげる。
場合によってデフォルト値を変えたい場合
テストなどをするときに、デフォルト値以外の値を入れて確かめたい。という場合があるかもしれない。
そんなときに使えるのが、state
。
状態変換メソッドは通常、Laravelの基本ファクトリクラスが提供するstateメソッドを呼び出す。
stateメソッドは、このファクトリ用に定義する素の属性の配列を受け取るクロージャを受け入れ、変更する属性の配列を返す必要がある。
/**
* ユーザーが一時停止されていることを示す
*
* @return \Illuminate\Database\Eloquent\Factories\Factory
*/
public function suspended()
{
return $this->state(function (array $attributes) {
return [
'account_status' => 'suspended',
];
});
}
テスト実行時やSeederでなにかデータを投入するときなどにデフォルトの値から変えたいという場合にstateは使うことができる。
読み出す際は、SeederファイルからTest::factory()->suspended()
という感じで呼び出すことができる。
参考