laravelでwebサービスを開発中にdb:seed
で
偽データを作成する際に初めから
決まった値をテーブルに入れておきたいことが発生しました。
Init用にseedrを個別で用意していたが
毎回 引数でクラス名を渡すのがメンドイ!
初めの一回だけ呼ばれたときにseedrが実行される抽象クラスを作成した。
何か他に良いやり方があったらおしえてくださいmm
まずは下記のコマンドを実行
php artisan make:seeder AbstractOnceSeeder
php artisan make:migration create_seed_flags_table
中身を修正
abstract class AbstractOnceSeeder extends Seeder
{
abstract public function runOnce();
public function run()
{
$className = get_class($this);
$isSeeded = DB::table('seed_flags')->where('name', $className)->first();
if ($isSeeded) {
return;
}
$this->runOnce();
DB::table('seed_flags')->insert(['name' => $className]);
}
}
return new class extends Migration
{
/* 省略 */
public function up(): void
{
Schema::create('seed_flags', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
});
}
/* 省略 */
};
一回だけ実行したいseederを作成するコマンドを実行。
※category用のモデルやテーブルは用意されている前提です
php artisan make:seeder InitCategorySeeder
class InitCategorySeeder extends AbstractOnceSeeder
{
public function runOnce(): void
{
$InitCategories = [
'HOGE',
'FUGA',
'PIYO',
];
foreach ($InitCategories as $category) {
Category::create(['name' => $category]);
}
}
}
そしたらDatabaseSeederにて下記のように呼び出すことで
一回だけ呼び出される。
class DatabaseSeeder extends Seeder
{
public function run(): void
{
/* 省略 */
//default値が存在するseeder
//seed_flagsをみて走るか来まる
$this->call([
InitCategorySeeder::class,
]);
/* 省略 */
}
}
あとはseederを実行。
php artisan db:seed