【Laravel】シーディングで初期データを入れる方法

Laravel

データベースを作成したばかりの時は中身が空である。

そこで手っ取り早くレコードをまとめて登録できるのがシーディングと呼ばれるもので、それらを登録するファイルがシーダーファイルである。テストデータの登録とかに使う。

大まかなながれ

シーダーファイルを作成

コマンドで一気に作成できる。

シーダーファイルの中身を記述

データを一気に流し込む。

シーディングの実行対象として登録する

シーダーファイルを作成しただけでは意味がなくて、シーディング実行ファイルであることを伝える必要がある。

シーディングを実行する

シーダーファイルを作成する

以下のコマンドを打つと、シーダーファイルが作成される。

sail artisan make:seeder SampleTableSeeder

シーダーファイルの中身を記述

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Sample;

class SampleTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $samples = [
            'title' => 'sample1',
            'title' => 'sample2',
            'title' => 'sample3',
            'title' => 'sample4',
            'title' => 'sample5',
        ];

        foreach ($samples as $sample) {
            Sample::create($sample);
        }
    }
}

Seederクラスを継承してSampleTableSeederクラスをつくっていることがわかる。

シーディングの実行対象として登録する

作成したシーディングファイルは、database/seeders/DatabaseSeeder.phpに登録する必要がある。

<?php

namespace Database\Seeders;

use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        // 以下を追加
        $this->call(SampleTableSeeder::class);
    }
}

$thisとcallメソッド

このコードにおける$thisは、DatabaseSeederクラスのインスタンスを指す。

DatabaseSeederSeederクラスを継承していて、Seederクラスにはcallメソッドが定義されている。このため、$this->call(SampleTableSeeder::class);という記述は、DatabaseSeederクラスのインスタンスでcallメソッドを呼び出していることになります。

  • $this: 現在のDatabaseSeederクラスのインスタンス。
  • call: 親クラス(Seeder)から継承したメソッド。このメソッドは、指定したSeederクラス(ここではSampleTableSeeder)を実行します。

シーディングを実行する

sail artisan db:seed

2つめのシーダーファイルを実行する時

SampleTableSeederを実行した後に、Sample2TableSeederを作成した場合、そのままシーディングを実行するとSampleTableSeederもSample2TableSeederも両方実行されてしまいます。

ここで何が悪いかというと、SampleTableSeederは既に実行済みなのでレコードが重複してしまう。

そんな時は、新しく作成したシーダーファイルのみ(Sample2TableSeeder)を指定することで実行するファイルだけを実行対象にすることができる。

--classオプションをつけて、シーダーファイルを指定する

sail artisan db:seed --class=Sample2TableSeeder

作成したレコードを確認する

mysql> select * from samples;

作成するレコードが多すぎたら流石に大変じゃないか??

シーディングを使えばレコードをまとめて登録できるが、仮に数百行ものレコードがあったとしたら流さすがに辛い。

そもそも仮のデータを登録するとかなら何も考えずにデータそのものを作ってくれるとありがたいな〜!なんて思うはず。(例えば重複しないように人の名前を考えるとか結構大変そう)

そんな時はfactoryという機能が上記の悩みを解決してくれる。

その辺は他の記事で解説予定!今回のシーディングとも関連する話だよ!