はじめに
こんばんは。
夜中子供が寝ているときに粛々と仕事と勉強をしております。
表題通りlaravel8でテストデータを作ったのですが、昔やってたlaravelのバージョンとは作り方違ってたので、備忘録として残しておきます。
本番
1. コンフィグの修正
config/app.php を修正して fakerで日本語を使用できるようにします。
'faker_locale' => 'ja_JP',
1. Factory作成
makeコマンド実行
$ php artisan make:factory UserProfileFactory Factory created successfully.
できたFactoryクラスを以下みたいに修正
<?php namespace Database\Factories; use App\Model\UserProfile; use Illuminate\Database\Eloquent\Factories\Factory; class UserProfileFactory extends Factory { protected $model = UserProfile::class; // 対象となるModelクラスを指定 public function definition() { // return値の値を作成(fakerを使ってダミーデータを作成) return [ 'name' => $this->faker->name, 'postal_code' => $this->faker->postcode(), 'prefecture' => $this->faker->prefecture(), 'address' => $this->faker->city() . $this->faker->streetName() . $this->faker-> streetAddress() ]; } }
2. Modelに必要なtraitをuseする
makeコマンド実行
php artisan make:model UserProfile Model created successfully.
作成されたmodelには HasFactory traitがuseされていると思いますが、makeコマンド介さずにmodelクラスを作った場合は以下のように HasFactory traitをuseします。
<?php namespace App\Model; use Database\Factories\UserProfileFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; class UserProfile extends Model { use HasFactory; // ← 対象のtrait protected static function newFactory() { return UserProfileFactory::new(); // ← 対象のFactoryを指定する } }
3. SeederでFactoryを指定してテストデータを作成する
makeコマンド実行
$ php artisan make:seeder UserProfileSeeder Seeder created successfully.
できたSeederファイルでFactoryを使用してデータを作成
<?php namespace Database\Seeders; use App\Model\UserProfile; use Illuminate\Database\Seeder; class UserProfileSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { UserProfile::factory(100)->create(); // これで100件のテストデータが作成できる // テストデータの一部 or 全てを上書きしたい場合 UserProfile::factory()->create([ 'name' => 'あいうえお' // nameだけテストデータではなく 「あいうえお」 にする ]); } }
番外編 factoryで使用するfakerに新たなメソッドを生やす
作成したfactoryクラスの親クラスである Illuminate\Database\Eloquent\Factories\Factory に存在している withFaker() をオーバライドして以下のように新たにproviderを作ります。
protected function withFaker()
{
$faker = parent::withFaker();
$faker->addProvider(new class($faker) extends \Faker\Provider\Base {
public function ngWord(): string
{
return $this->generator->randomElement([
'バカ',
'アホ',
'マヌケ'
]);
}
});
return $faker;
}
これで $this->faker->ngWord() が使えるようになります。
baseクラスを新たに作って生やしてもいいし、 HasFactory trait側のメソッドをオーバライドして対応とか、色々やり方はありそうです。
終わりに
久々にlaravel使っているんですが、テストデータとか作りやすいですね。
現場からは以上です。