【Laravel】Seederでテストデータを入れる3つの方法と使い分け方〜 DB::table() と updateOrCreate() の違いを徹底解説〜

laravelアイキャッチ Laravel

こんにちは、かつコーチです。

Laravelで開発していると、テストデータや初期データを登録したい場面は多くあります。

そんなときに便利なのが「Seeder」です。

本記事では、Seederでデータを登録する3つの方法と、それぞれの使いどころをわかりやすく解説します

DB::table()->insert() とは?

特徴

DB::table()はクエリビルダを使って直接SQLを実行する方法です。
Eloquentを使わないため、モデルのイベントやアクセサ・ミューテタが動かないので非常に高速です。

コード例

DB::table('blog_categories')->insert([
    ['id' => 1, 'name' => '未登録', 'slug' => 'unregistered'],
    ['id' => 2, 'name' => 'お知らせ', 'slug' => 'news'],
]);
項目内容
モデル使用しない(DBへ直接INSERT)
イベント発火しない(creating, createdなど)
タイプ生のSQLレベルの挿入
バリデーション無視される
主な用途初期データやマスターデータの一括投入(パフォーマンス重視)
戻り値なし(結果はboolean)

メリット・デメリット

メリット

  • 高速(Eloquentのオーバーヘッドがない)
  • 複数行をまとめてinsertできる
  • 軽量(モデルを経由しない)

デメリット

  • モデル側の処理(例:$castsHash::make() など)が自動で反映されない
  • 重複チェックなどを自分で書く必要がある

Model::create() を使う方法

特徴

create()はEloquentを通して1件ずつ登録する方法です。
モデルのイベントや$castsが動作します。

コード例

Admin::create([
    'name' => 'テスト管理者',
    'email' => 'test@example.com',
    'password' => Hash::make('password'),
]);

メリット・デメリット

メリット

高速でシンプル。

大量データに向く。

デメリット

モデルのイベントが発火しない。

バリデーションやロジックが効かない。

updateOrCreate() を使う方法

特徴

既に同じデータがある場合は更新し、なければ新規作成する便利なメソッドです。
重複を避けたいときに最適です。

コード例

Admin::updateOrCreate(
    ['email' => 'owner@example.com'],
    ['name' => 'Owner', 'password' => Hash::make('password')]
);

メリット・デメリット

メリット

重複を避けられる

モデルイベントが動く

デメリット

1件ずつ処理するため遅い

大量データには不向き

それぞれの使い分け方

シーン推薦方法
初期カテゴリや都道府県など固定データDB::table()->insert()
テスト管理者・初期ユーザーupdateOrCreate()
モデルロジックを通したい場合create()

実践例 : Seederで使い分ける

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        // マスターデータ
        DB::table('blog_categories')->insert([...]);

        // 管理者ユーザー
        Admin::updateOrCreate(
            ['email' => 'owner@example.com'],
            ['name' => 'Owner', 'password' => Hash::make('password')]
        );
    }
}

まとめ

💡簡単に言えば:

  • 速く大量に入れたい → DB::table()
  • 重複を避けて安全に入れたい → updateOrCreate()
  • モデルのロジックを通したい → create() or updateOrCreate()

迷ったときは「速度優先ならDB::table()、安全優先ならupdateOrCreate()」が基本!

コメント

タイトルとURLをコピーしました