データベースシーディングとファクトリの目的

Laravel では 「マイグレーション=テーブル構造の変化」「シーディング/ファクトリ=テーブル内容の生成」 を明確に分離しています。

  • シーディング (Seeder) … テーブルに「まとまった初期データ」や「開発用ダミーデータ」を投入する仕組み。

  • ファクトリ (Factory) … 1 レコード単位で Eloquent モデルを生成するための「ブループリント」。Faker を通じてランダムでも実在感のある値を生成できます。 laravel.comlaravel.com


1. ファクトリ ― モデル生成のブループリント

1-1. 作成と配置

bash
php artisan make:factory PostFactory # PostFactory.php が database/factories に生成される

生成されたクラスは Illuminate\Database\Eloquent\Factories\Factory を継承し、
definition() メソッドでカラム初期値を宣言します。

php
use Illuminate\Support\Str; class PostFactory extends Factory { protected $model = \App\Models\Post::class; public function definition(): array { return [ 'title' => $this->faker->sentence, 'slug' => Str::slug($this->faker->unique()->sentence), 'body' => $this->faker->paragraph(5), 'user_id' => User::factory(), // 関連モデルもネスト可 'is_published' => $this->faker->boolean, ]; } }

ポイント

  • protected $model で紐付くモデルを明示

  • Faker ロケールは config/app.phpfaker_locale で変更可

  • User::factory() のように 関係モデル も再帰的に生成可能 laravel.com

1-2. ステート (state) & シーケンス (sequence)

  • state() で「下書き」「公開済み」など属性セットを名前付きで用意。

  • sequence() で複数パターンを順番に適用し、一覧データを“均等”生成。

php
public function draft(): static { return $this->state(fn () => ['is_published' => false]); }

1-3. コールバック

afterMaking() / afterCreating() で、生成後に関連モデル追加やカスタム処理を注入できます。


2. シーディング ― データ投入クラス

2-1. シーダークラスの作成

bash
php artisan make:seeder UserSeeder # database/seeders/UserSeeder.php

標準で用意される DatabaseSeeder から call() で個別シーダーを呼び出す構成が推奨。

php
public function run(): void { $this->call([ UserSeeder::class, PostSeeder::class, ]); }

laravel.com

2-2. run() 内でのデータ生成パターン

用途 実装例 特徴
固定値の投入 DB::table('roles')->insert([...]); マスターテーブルなど
ファクトリ利用 User::factory()->count(50)->create(); ダミーユーザ 50 件
環境依存投入 if (app()->isProduction()) {...} 本番のみ/開発のみ切替

2-3. 実行コマンド

  • php artisan db:seedDatabaseSeeder を実行

  • php artisan db:seed --class=UserSeeder … 個別実行

  • php artisan migrate --seed … マイグレーション完了後にシーディング

  • php artisan migrate:fresh --seed … テーブル再作成+データ投入を一括

安全対策: 本番環境では --force オプション必須。CI/CD で自動投入する場合は注意。


3. シーディングとファクトリを連携する実例

php
// database/seeders/UserSeeder.php class UserSeeder extends Seeder { public function run(): void { // 1 管理者を固定値で User::factory()->admin()->create([ 'email' => 'admin@example.com', ]); // 2 一般ユーザをランダムに 50 件 User::factory()->count(50)->create(); // 3 各ユーザ 3 件の記事を紐付け User::all()->each(fn ($user) => Post::factory()->count(3)->for($user)->create() ); } }

admin() は UserFactory 側で state() 定義済みと想定


4. よくある落とし穴とベストプラクティス

症状 / 誤解 原因 解決策
「外部キー制約違反」で失敗 生成順序が不適切 親→子 の順に call() / create()
本番で誤って大量ダミー投入 環境判定不足 if (app()->isProduction()) return; でガード
Factory の重複キー unique() の使いすぎ テスト後は DatabaseTransactions でリセット/unique(false)
Faker 生成が重い count(10000) など大量生成 バッチで分割 or DB バルクインサートを検討

5. Laravel 11 での追加ポイント

  • 新アプリケーション構造 に合わせ、database/seedersdatabase/factories は変わらず利用可。

  • php artisan make:model Post -mf で「モデル+ファクトリ+マイグレーション」を一括生成可能。

  • テストコードでは Illuminate\Foundation\Testing\RefreshDatabase / DatabaseMigrations トレイトを使うと、テストごとにマイグレーション → シーディングを自動実行できる。 laravel.com


まとめ

  • ファクトリ … モデル 1 件を“リアルな属性”で組み立てる設計図。

  • シーダー … 複数テーブル・複数レコードを協調して投入するスクリプト。

  • 開発環境ではダミーデータを潤沢に、本番環境では最小構成だけを投入することで「移行とテストの手間」を大幅に削減できます。

  • Laravel 11 では改良された CLI とアプリ構造により、これらの作業がさらに簡潔になりました。

これらを活用し、マイグレーション → シーディング → テスト という一連のデータライフサイクルを自動化すると、開発速度と再現性が大幅に向上します。

ChatGPT4o 生成日:2025/06/23