🕌

Laravel database/seeders以外にSeederクラスを配置して実行する

2024/04/17に公開

はじめに

Laravelで初期データを作成する際にSeederクラスを使うケースがあると思います。
その際に初めから用意されているdatabase/seeders配下のDatabaseSeederクラスを使ったり、
同じ階層にSeederクラスを追加して対応しているかと思います。

でも、実は別のところに追加しても実行できたりします。

今回はそんなちょっとした小ネタを書いておきたいと思います。

環境

  • PHP 8.3.6
  • Laravel 11.4.0

やってみる

まずDatabaseSeederクラスを指定して実行してみると、次のようになるかと

% php artisan db:seed --class=\\Database\\Seeders\\DatabaseSeeder

   INFO  Seeding database.  

では、別のところにクラスを作ってみましょう。

場所はどこでもいいですが、autoloadの設定が入っているところにする必要があるので、
今回はapp配下にクラスを1つ作ります。

内容は楽をしたいので、DatabaseSeederクラスをコピーして、ネームスペースだけ書き換えます
※登録するデータも一部書き換えています。

app/DatabaseSeeder.php
<?php

namespace App;

use App\Models\User;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        User::factory(10)->create();
    }
}

追加したapp/DatabaseSeeder.phpを実行してみます。

% php artisan db:seed --class=\\App\\DatabaseSeeder

   INFO  Seeding database.  

出来ましたね🥳

なぜ出来るのか

db:seedコマンドの処理を見るとオプションで渡されたclass名を98行目でインスタンスを生成しているため実行できるわけですね。

https://github.com/laravel/framework/blob/v11.4.0/src/Illuminate/Database/Console/Seeds/SeedCommand.php#L80-L101

注意点としては、

  • classオプションは\\を先頭につけておかないとDatabase\\Seeders\がつく
  • Seederクラスは必ず\Illuminate\Database\Seederを継承して、runメソッドを実装しておく

まとめ

database/seeders配下で作っておけば、特に気にする必要もないですが、
Laravelのパッケージ開発を行っている場合、
パッケージ配下にseedersディレクトリを作ったりするかもしれないのでそういう時に使えるかもしれないですね。

Discussion