Laravel シーディングとファクトリ

シーディング

データベースにダミーデータを追加

シーダークラスを作成

sail artisan make:seeder シーダークラス名
database/seedersフォルダの中にシーダクラスが生成される

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        //
    }
}

クエリビルダで追加

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        DB::table('products')->insert([
            'product_name' => 'ノート5冊セット',
            'price' => 600,
            'created_at' => '2023-06-01 00:00:00',
            'updated_at' => '2023-06-01 00:00:00',
            'vendor_code' => 1111
        ]);
    }
}

Eloquent ORMで追加

<?php

namespace Database\Seeders;

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

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $product = new Product([
            'product_name' => 'ノート5冊セット',
            'price' => 600,
            'vendor_code' => 1111        
        ]);
        $product->save();
    }
}

シーダークラスを実行

  • --classオプションに指定したシーダークラスのみが実行
sail artisan db:seed --class=シーダークラス名
  • --classオプションをつけない場合、database/seedersフォルダの中にあらかじめ用意されているDatabaseSeederクラスが実行
sail artisan db:seed

複数のシーダークラスを一度に実行するにはDatabaseクラス内で他のシーダークラスを呼び出す
database/seeders/DatabaseSeeder

<?php

namespace Database\Seeders;

// 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([
+            シーダー1Seeder::class,
+            シーダー2Seeder::class            
        ]);        
    }
}
<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class ProductSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        //
    }
}

ファクトリ

ダミーデータを生成

  • ファクトリの命名規則
    「対象となるテーブル名の単数形(モデル名)+Factory」という名前
    ファクトリではこの命名規則に従うことで、Laravel側がモデルとファクトリを自動的に紐づけてくれます。

例えばproductsテーブル(Productモデル)用のファクトリであればProductFactory、vendorsテーブル(Vendorモデル)用のファクトリであればVendorFactoryです。このように命名することで、Laravel側はProductモデルとProductFactory、VendorモデルとVendorFactoryを自動的に紐づけてくれます。

  • Fakerのランダム値の日本語化
    config/app.php
    'faker_locale'の値に'ja_JP'を指定。
//======== 前略 ========

    /*
    |--------------------------------------------------------------------------
    | Faker Locale
    |--------------------------------------------------------------------------
    |
    | This locale will be used by the Faker PHP library when generating fake
    | data for your database seeds. For example, this will be used to get
    | localized telephone numbers, street address information and more.
    |
    */

    'faker_locale' => 'ja_JP',

//======== 後略 ========

ファクトリを作成

sail artisan make:factory ファクトリ名

database/factoriesフォルダの中にファクトリが生成される。
definition()メソッドの中で以下のように連想配列を返すことで、ダミーデータを生成

<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Vendor>
 */
class VendorFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        return [
            'vendor_code' => fake()->randomNumber(5, true),
            'vendor_name' => fake()->company()                       
        ];
    }
}

fake()ヘルパ関数を使うことで、ファクトリからFakerというPHPライブラリにアクセスでき、ダミーデータ用のさまざまなランダム値を生成
Fakerの代表的なメソッド

メソッド 生成されるランダム値 引数
name() 姓名 木村 舞 'male'を指定した場合は男性の姓名、'female'を指定した場合は女性の姓名が生成される(オプション)。
lastName() 工藤 なし
firstName() 裕太 'male'を指定した場合は男性名、'female'を指定した場合は女性名が生成される(オプション)。
kanaName() カタカナの姓名 ササダ アケミ 'male'を指定した場合は男性の姓名、'female'を指定した場合は女性の姓名が生成される(オプション)。
lastKanaName() カタカナの姓 イシダ なし
firstKanaName() カタカナの名 シュウヘイ 'male'を指定した場合は男性名、'female'を指定した場合は女性名が生成される(オプション)。
email() メールアドレス(ドメイン部分もランダムなので、実在する可能性がある) hideki.fujimoto@aoyama.org なし
safeEmail() 安全なメールアドレス(ドメイン部分が数種類の中から固定であり、実在しない) akira61@example.com なし
address() 住所 8983502 長崎県伊藤市北区鈴木町宮沢1-10-8 ハイツ中村109号 なし
postcode() 郵便番号 2746333 なし
city() 田辺市 なし
streetName() 山岸町 なし
streetAddress() 町以降の住所 石田町西之園4-2-9 なし
secondaryAddress() 建物以降の住所 ハイツ吉本101号 なし
phoneNumber() 電話番号 06-1841-5463 なし
company() 会社名 株式会社 山口 なし
realText() 文章 ぼくには一昨日おとといたいへん元気な便たよりがあったんだ。レールを七つ組み合わせました。そのとき舟。 第1引数は最大文字数(最小値は10、初期値は200)。第2引数はインデックスサイズ(1〜5を指定、初期値は2)。インデックスサイズが大きいほど自然な文章になる。
randomNumber() 整数 8424749 第1引数は桁数(1〜9を指定、初期値はnull)。第2引数は桁数を固定するかどうか(trueまたはfalseを指定、初期値はfalse)。桁数を固定しない場合(第2引数がfalseの場合)、1桁から第1引数で指定した桁数までの整数が生成される。
numberBetween() 指定した範囲内の整数 1615557015 第1引数(初期値は0)から第2引数(初期値は2147483647)までの整数が生成される。
dateTime() 日時 1976-07-20 02:35:16 第1引数は日時の最大値(初期値は'now')。第2引数はタイムゾーン(初期値はシステムのデフォルトのタイムゾーン)。
date() 日付 1988-01-13 第1引数はフォーマット(初期値は'Y-m-d')、第2引数は日付の最大値(初期値は'now')。
time() 時間 15:28:38 第1引数はフォーマット(初期値は'H:i:s')、第2引数は時間の最大値(初期値は'now')。
dateTimeBetween() 指定した期間内の日時 2003-05-26 09:45:02 第1引数(初期値は'-30 years')から第2引数(初期値は'now')までの日時が生成される。第3引数はタイムゾーン(初期値はシステムのデフォルトのタイムゾーン)。

ファクトリでダミーデータの各カラムの値を定義したら、あとはシーダークラスで以下のようにモデル名::factory()->create();と記述すれば、ダミーデータをテーブルに追加できます。

<?php

namespace Database\Seeders;

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

class VendorSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void {
        // VendorFactoryクラスで定義した内容にもとづいてダミーデータを生成し、vendorsテーブルに追加する
        Vendor::factory()->create();
    }
}

以下のようにcount()メソッドを使うことで、生成するダミーデータの数を指定することもできます。

<?php

namespace Database\Seeders;

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

class VendorSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void {
        // VendorFactoryクラスで定義した内容にもとづいてダミーデータを5つ生成し、vendorsテーブルに追加する
        Vendor::factory()->count(5)->create();
    }
}