章: 第2章: データベース応用
「自分の環境でしか動かない」——テストデータの差異が引き起こす問題
開発者Aはユーザーを手動で5件登録している。開発者BはDB初期化後に1件しかない。CI環境には何もない——。こうした「環境ごとのデータ差異」がテスト結果の不一致や、動作確認の手戻りを引き起こします。
Seederを使うと php artisan db:seed コマンド一発で誰でも同じ初期データを再現できます。
Seederの実装
<?php
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder {
public function run(): void {
User::factory()->count(10)->create();
}
}
class UserFactory extends Factory {
public function definition(): array {
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
];
}
}
// 実行: php artisan db:seed
手動データ投入 vs Seeder
| 観点 | 手動でデータ投入 | Seederを使う |
| 再現性 | 環境ごとに異なる | db:seed で誰でも同じ |
| チーム開発 | 誰かのデータが違う | 統一された初期状態 |
| CI/CD | 自動化できない | --seed オプションで組み込める |
| リセット | データが混ざる | migrate:fresh --seed で完全初期化 |
チェックポイント:
php artisan migrate:fresh --seedでテーブルをリセットして初期データを投入し直せます。開発中のデータ汚染をリセットするのに便利です。
Factoryの状態(State)を使う
<?php
class UserFactory extends Factory {
public function definition(): array {
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'role' => 'user',
'verified' => true,
];
}
// 管理者ユーザー用のState
public function admin(): static {
return $this->state(['role' => 'admin']);
}
}
// DatabaseSeeder
class DatabaseSeeder extends Seeder {
public function run(): void {
User::factory()->count(50)->create();
User::factory()->admin()->count(3)->create();
}
}
チェックポイント: FactoryのStateを使うと「管理者5名、一般ユーザー50名」のような現実的なデータセットを宣言的に作れます。
まとめ & 次のステップ
- Seederはテスト・開発用の初期データをコードで管理し、誰でも再現できる
- Factoryを組み合わせることで現実的なデータセットをランダム生成できる
migrate:fresh --seedでいつでもクリーンな初期状態に戻せる
次回は論理削除とソフトデリートを学びます。物理削除せずに「削除済み」として扱い、データを安全に保持する方法です。