マスタテーブルの初期データ、どうしてる?
マイグレーションでマスターテーブルを作成時、初期データを投入しておきたいケースが有る。
その場合、Seederを作成して下記のようなコマンドで実行するように記載されているケースをよく見る
php artisan db:seed --class=HogeSeeder
面倒くさいし人的エラーの元になりそう
これだと個人開発では良いが、 開発途中で追加されたテーブルでさらに新しく開発者がアサインされてきた場合 などに、いちいちこれを実行してもらうのはかなり面倒くさいし、マニュアルに書くのも忘れそう。
大規模開発になるほど負の遺産と化すだろう。
うっかり
php artisan db:seed
までで実行してメインのデータがテストデータに初期化されてしまう恐れもある。
マイグレーション実行時にデータを入れてしまいたい
そもそも、初期データなのだから、マイグレーションの実行(テーブル作成)と一緒に入ってこなければおかしいはず。
だって、後から同一テーブルのデータ型が変わったりした場合、Seederも書き換えないといけないし、そうすると変更経緯がよくわからなくなってしまう。
そんなわけで調べてみたら、できるじゃん。
https://owenconti.com/posts/calling-laravel-seeders-from-migrations
つまり、Seederを作成するところまでは同じだが、db:seed
の対象にはせず、マイグレーション実行時にdb:seed --class=HogeSeeder
を実行すれば良いということ。
上記リンクを読めば95%くらい理解できると思うが手順を書いていく。
作成手順
1. マイグレーションとSeederを作成
php artisan make:migration create_hoges_table
php artisan make:seeder HogeSeeder
2. マイグレーションを記述
ニ箇所に追記があるので注意。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Artisan; // ← 追記
class CreateHogesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('hoges', function (Blueprint $table) {
$table->id();
$table->string('name')->comment('ラベル');
$table->timestamps();
});
// 追記:初期データの投入
Artisan::call('db:seed', ['--class' => 'HogeSeeder']);
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('hoges');
}
}
3. Seederを記述
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class HogeSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
\DB::table('hoges')->insert(
[
[
'id' => 1,
'name' => 'ほげ',
'created_at' => now()
],
[
'id' => 2,
'name' => 'ふが',
'created_at' => now()
],
]
);
}
}
4. マイグレーション実行
php artisan migrate
注意点
テーブルの作成に成功してSeederの実行に失敗した場合、手動でテーブルの削除が必要になる。
- migration履歴に残らない
- 当然ロールバック対象にもならない
なのでまずはマイグレーションとSeederを分けて、それぞれの実行に成功してからマージするのが良いと思う。