Laravelでデータベースに初期データやテスト用ダミーデータを一括投入したいときに欠かせないのがSeeder(シーダー)です。
基本実行は php artisan db:seed や php artisan db:seed --class=Seeder名 コマンド1つで行えますが、実務では「Factoryとどう連携してダミーデータを自動生成するか」「本番環境で安全にマスタデータだけを投入するにはどう設計すべきか」といった運用面まで押さえておく必要があります。
この記事では、LaravelのSeederの基本概念から、作成・書き方(DBファサード/Eloquent/Factory連携/冪等設計)、DatabaseSeederでの環境分岐、実行コマンド一覧、本番運用の注意点、よくあるエラー対処までを網羅して分かりやすく解説します。
LaravelのSeederとは?Migration・Factoryとの役割の違い
Seeder(シーダー)とは、データベースに初期レコードやテスト用データを自動で流し込む(Seed=種をまく)ための仕組みです。
Laravel開発でSeederを活用する主なメリットは次のとおりです。
- 環境構築の自動化:新しい開発メンバーが参加した際やDockerコンテナを立ち上げた際に、1コマンドで動作確認用データを用意できる
- テストデータの再現性:手動入力の手間を省き、チーム全員が常に同じ条件のデータで開発・検証を行える
- マスタデータの確実な投入:都道府県一覧やユーザー権限、初期管理者アカウントなど、アプリの稼働に必須の初期データを安全に登録できる
Migration / Factory / Seeder の役割分担
Laravelのデータベース周辺機能は似た用語が多いため、それぞれの役割を整理しておきましょう。
| 機能 | 主な役割 | 例え |
|---|---|---|
| Migration(マイグレーション) | テーブルの作成・カラム定義・インデックス追加など「テーブル構造」を管理する | データベースの「設計図・器」 |
| Factory(ファクトリ) | Fakerを利用して氏名・メールアドレスなどの「ダミーデータ」を定義・自動生成する | データの「製造工場」 |
| Seeder(シーダー) | Factoryや直接定義したデータを「データベースへ投入する処理・手順」を担う | データを器へ「流し込む作業員」 |
マイグレーションの基礎については【Laravel】マイグレーション完全ガイド|作成・実行・ロールバック・カラム変更まで徹底解説を、Fakerによるデータ生成はLaravel Fakerを使ったデータ生成の基本と効果的な活用法も合わせて参考にしてください。
Seederファイルの作成方法(make:seeder)
Seederクラスは、Artisanコマンドを使って簡単に生成できます。
Seeder作成コマンド
ターミナルで以下のコマンドを実行します。
php artisan make:seeder UserSeeder
コマンドを実行すると、database/seeders/UserSeeder.php が生成されます。コマンドの詳細はmake:seeder — シーダーの生成コマンドで解説しています。
Seederの命名規則
Seederのクラス名は 対象モデル名(またはテーブル名)+ Seeder(アッパーキャメルケース)にするのが標準的なルールです。
UserSeeder(ユーザーテーブル用)PostSeeder(投稿テーブル用)AdminUserSeeder(初期管理者データ用)
生成されるSeederファイルの初期構造
作成された直後のSeederファイルは次のようになっています。
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// ここにデータ投入ロジックを記述する
}
}
Seederが実行されると、この run() メソッド内に書かれたコードが呼び出されます。
Seederの具体的な書き方4パターン
run() メソッド内にデータを投入するコードを書く際、実務では主に4つのアプローチがあります。用途に応じて使い分けましょう。
パターン1: DBファサード(クエリビルダ)を使う
DB::table('テーブル名')->insert(...) を使って直接SQLのINSERT文を発行する方法です。モデルイベントやマスアサインメント(fillable)の影響を受けず、シンプルな初期値投入に適しています。
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
class UserSeeder extends Seeder
{
public function run(): void
{
DB::table('users')->insert([
[
'name' => '管理者 太郎',
'email' => 'admin@example.com',
'password' => Hash::make('password123'),
'role' => 'admin',
'created_at' => now(),
'updated_at' => now(),
],
[
'name' => '一般 花子',
'email' => 'user@example.com',
'password' => Hash::make('password123'),
'role' => 'general',
'created_at' => now(),
'updated_at' => now(),
],
]);
}
}
※DBファサードの insert では created_at や updated_at が自動設定されないため、配列内で明示的に now() を指定する必要があります。
パターン2: Eloquentモデルを使う
Eloquentモデルの create() メソッドを使う方法です。タイムスタンプが自動補完され、モデルのミューテタやキャスト機能が有効になります。
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserSeeder extends Seeder
{
public function run(): void
{
User::create([
'name' => '開発テストユーザー',
'email' => 'test@example.com',
'password' => Hash::make('password123'),
]);
}
}
注意点として、モデル側(User.php)で $fillable または $guarded が正しく設定されていないと MassAssignmentException が発生します。
パターン3: Factory連携で大量ダミーデータを生成する(推奨)
開発・テスト環境用で数十〜数百件のダミーデータを用意したい場合、Factory(ファクトリ)と連携するのが最も効率的です。
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\User;
use App\Models\Post;
class UserSeeder extends Seeder
{
public function run(): void
{
// 1. ダミーユーザーを50件一括生成
User::factory()->count(50)->create();
// 2. リレーションを持たせて生成(各ユーザーに記事を3件ずつ紐付け)
User::factory()
->count(10)
->has(Post::factory()->count(3))
->create();
}
}
Factoryを活用することで、Fakerによるリアルなダミー値(名前、住所、本文、日時など)が自動生成され、テストシナリオの検証が格段にスムーズになります。
パターン4: updateOrCreate / upsert で再実行可能な「冪等性」を持たせる
マスタデータ(権限一覧、カテゴリ一覧、固定の設定値など)を投入する際、insert や create をそのまま使うと、2回目のSeeder実行時に「Duplicate entry(重複エラー)」が発生してしまいます。
何度実行しても同じ安全な状態を保つ(=冪等性(べきとうせい)の確保)ために、updateOrCreate または upsert を利用するのがベストプラクティスです。
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\Category;
class CategorySeeder extends Seeder
{
public function run(): void
{
$categories = [
['slug' => 'news', 'name' => 'お知らせ'],
['slug' => 'tech', 'name' => '技術情報'],
['slug' => 'column', 'name' => 'コラム'],
];
foreach ($categories as $data) {
// slugが一致するレコードがあれば更新、なければ新規作成
Category::updateOrCreate(
['slug' => $data['slug']],
['name' => $data['name']]
);
}
}
}
DatabaseSeederの設計と環境ごとの切り分け
個別のSeederを作成したら、親玉となる database/seeders/DatabaseSeeder.php に登録します。
$this->call() による実行順序の制御
外部キー制約が存在する場合、子テーブルのSeederを先に実行すると制約エラーになります。DatabaseSeeder で親テーブルから順番に呼び出すように記述します。
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$this->call([
RoleSeeder::class, // 1. 権限マスタ(親)
UserSeeder::class, // 2. ユーザーデータ
CategorySeeder::class, // 3. カテゴリマスタ(親)
PostSeeder::class, // 4. 投稿データ(子)
]);
}
}
環境(local / production)による投入データの分離
本番環境に「テスト用の偽ユーザー」が紛れ込む事故を防ぐため、app()->isLocal() や app()->environment() を使って環境ごとに実行するSeederを切り分けるのがプロの現場の鉄則です。
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
// 全環境共通で必要なマスタデータ
$this->call([
RoleSeeder::class,
CategorySeeder::class,
]);
// ローカル開発・テスト環境のみで実行するダミーデータ
if (app()->isLocal()) {
$this->call([
DummyUserSeeder::class,
DummyPostSeeder::class,
]);
}
}
}
Laravel Seederの実行コマンド一覧と使い分け
Seederを実行するArtisanコマンドを用途に合わせて整理しました。php artisanの使い方完全ガイドも参考にしてください。
1. 全Seederを実行する(基本)
php artisan db:seed
DatabaseSeeder の run() メソッドを実行します。登録されているすべてのSeederが順番に実行されます。コマンド詳細はdb:seed — データベースにシードデータを投入するコマンドを参照してください。
2. 特定のSeederだけを単体実行する(開発時に多用)
php artisan db:seed --class=UserSeeder
--class オプションを指定すると、DatabaseSeeder に登録していないSeederであってもピンポイントで単体実行できます。新規Seederの動作確認や、特定テーブルのみデータを再投入したいときに最適です。
3. マイグレーションと同時にSeederを実行する
# テーブルをすべて削除して再構築した上で、Seederを実行
php artisan migrate:fresh --seed
# 特定のSeederだけを指定してマイグレーションと同時に実行
php artisan migrate:fresh --seed --seeder=UserSeeder
migrate:fresh --seed は、開発中にデータベースを初期状態へリセットしてテストデータを入れ直す際の定番コマンドです(全テーブルがDROPされるため、本番環境では絶対に実行しないでください)。
4. 本番環境で強制実行する(–force)
php artisan db:seed --force
本番環境(APP_ENV=production)では、誤操作を防ぐために「本当に実行しますか?」という確認プロンプトが表示されます。CI/CDパイプラインやデプロイスクリプトなど非対話形式で実行する場合は、--force オプションを付与してプロンプトをスキップします。
本番環境(Production)でSeederを運用する際の重要注意点
本番環境でのSeeder実行は、一度のミスがデータ損失やサービス障害につながる危険性があります。以下の安全対策を必ず確認しておきましょう。
1. Faker(Factory)の本番依存関係エラーに注意
Laravelの標準構成では、ダミーデータ生成ライブラリである fakerphp/faker は composer.json の require-dev(開発環境用)に記載されています。
本番デプロイ時に composer install --no-dev を実行している環境で、Factoryを呼び出すSeederを動かすと、「Class ‘Faker\Factory’ not found」エラーでSeederが停止します。本番環境で実行するSeederにはFactoryを含めず、固定値や環境変数を使った安全なコードにしましょう。
2. 冪等性(Idempotency)を徹底する
デプロイパイプラインで php artisan db:seed を自動実行する場合、Seederは何度実行されても既存データに悪影響を与えない設計になっている必要があります。前述の updateOrCreate や upsert を活用し、主キーやユニークキーの重複エラーが起きないようにしてください。
3. 実行前のDBバックアップ
本番環境でSeederを流す前には、万が一の誤動作や上書きに備えて必ずデータベースのスナップショットやダンプ(バックアップ)を取得しておく運用フローを徹底しましょう。
4. 大量データ投入時のバルクインサートとメモリ節約
何千・何万件ものレコードを User::create() で1件ずつループ処理すると、SQL発行回数が膨大になり実行時間が何十分もかかったりメモリ枯渇を起こしたりします。
大量データ投入時は、次のように insert によるバルクインサート(一括挿入)や chunk を活用し、トランザクションで囲むと高速かつ安全です。
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class LargeDataSeeder extends Seeder
{
public function run(): void
{
$data = [];
$now = now();
for ($i = 1; $i <= 5000; $i++) {
$data[] = [
'code' => sprintf('ITEM-%05d', $i),
'name' => "商品名 {$i}",
'created_at' => $now,
'updated_at' => $now,
];
// 1,000件ごとに分割してバルクインサート
if (count($data) >= 1000) {
DB::table('items')->insert($data);
$data = [];
}
}
if (!empty($data)) {
DB::table('items')->insert($data);
}
}
}
Seederでよくあるエラーと解決手順(トラブルシューティング)
Seederの作成・実行時によく遭遇するエラーとその解決方法をまとめました。
1. Class “Database\Seeders\XxxSeeder” not found
新規作成したSeederや手動でリネーム・移動したSeederが認識されない場合のエラーです。Composerのオートロードマップが古いことが原因です。
composer dump-autoload
上記コマンドを実行してオートロードキャッシュを再生成してください。
2. db:seedを実行したのにデータが入らない
php artisan db:seed を実行したにもかかわらずテーブルにデータが追加されない場合、DatabaseSeeder.php の run() メソッド内でそのSeederクラスが $this->call() されていない可能性が最も高いです。
単体テストしたい場合は php artisan db:seed --class=Seeder名 を実行するか、DatabaseSeeder.php の配列にクラス名を追加してください。
3. Cannot add or update a child row: a foreign key constraint fails
外部キー制約エラーです。親テーブルのレコードが存在しない状態で子テーブルのデータを挿入しようとすると発生します。
- 解決策1:
DatabaseSeederでの実行順序を見直し、親テーブルのSeederを先に実行する - 解決策2:テストデータ生成用であれば、一時的に外部キー制約を無効化する(例:
Schema::disableForeignKeyConstraints()/Schema::enableForeignKeyConstraints())
4. Integrity constraint violation: 1062 Duplicate entry
主キー(id)や unique 制約が設定されたカラム(emailやコードなど)で値が重複している場合に発生します。
- Seeder内で
updateOrCreateやfirstOrCreateを使用する - 開発環境であれば事前に
php artisan migrate:fresh --seedでテーブルを初期化する
5. Add [xxx] to fillable property to allow mass assignment
Eloquentモデルの Model::create([...]) を使用した際に、モデルクラス側の $fillable プロパティにカラム名が指定されていないことが原因です。モデルに protected $fillable = ['xxx', ...]; を定義するか、Seeder内では DB::table('...')->insert(...) を利用してください。
よくある質問(FAQ)
SeederとFactoryはどう使い分けるべき?
「マスタデータ(固定値)」はSeederに直接定義し、「テスト用ダミーデータ(大量生成)」はFactoryで雛形を作りSeederから呼び出すのが王道の使い分けです。ユニットテストやフィーチャーテスト内でもFactoryを直接 User::factory()->create() のように再利用できます。
Seederの実行結果をロールバック(元に戻す)はできる?
マイグレーションのような「Seeder専用のロールバックコマンド」は標準では用意されていません。開発環境であれば php artisan migrate:fresh --seed で作り直すのが最も手軽です。本番環境でロールバックが必要な場合は、事前にDBバックアップを取得しておくか、データを削除する専用のコマンド・スクリプトを用意します。
まとめ
LaravelのSeederは、初期マスタデータの登録から開発環境のダミーデータ作成まで、データベース操作の自動化に欠かせない重要機能です。
- 作成:
php artisan make:seeder Seeder名 - 実行:
php artisan db:seed(全実行)またはphp artisan db:seed --class=Seeder名(単体実行) - テストデータ:Factoryと連携して
Model::factory()->count(10)->create()で効率的に生成 - マスタデータ:
updateOrCreateを活用して何度実行しても安全な冪等性を確保 - 本番運用:
DatabaseSeederでapp()->isLocal()による環境分岐を行い、Fakerの混入や誤投入を防ぐ
大量のシードデータを一括投入する際のトランザクション活用や、在庫引き当て・決済処理などの同時実行テストに必要な排他ロックの実装については、Laravel lockForUpdate()の使い方|排他ロック(悲観的ロック)とトランザクションの実装・注意点 および Laravelトランザクションの基礎と効果的な活用方法を徹底解説 もあわせてご覧ください。
まずは特定のSeederを --class オプションで単体実行するところから試し、慣れてきたらFactory連携や環境ごとの切り分けを取り入れて、チーム開発の効率を高めていきましょう。

コメント