laravel
laravel5.5

関連pivotテーブルを持つダミーデータをFaker使って入れる時のSeederの書き方

今日書くこと

タイトルどおり。
Laravel 5.5で実装してみたけど、5系ならどれでも似たり寄ったりだと思う。

店舗一覧があって、その店舗にユーザが所属するManyToManyな関係。

ユーザは複数の店舗に所属することが可能。

  • ナウい書店本店
    • ユーザ1
    • ユーザ3
  • ナウい書店大阪店
    • ユーザ1
    • ユーザ5
    • ユーザ7
  • ナウい書店マサチューセッツ店
    • ユーザ5

テーブル構成

  • shops (店舗マスタ)
  • users (ユーザマスタ)
  • shop_user (店舗×ユーザのpivotテーブル)

Seeder

おいらのpivotテーブルにはcreated_byとcreated_atが存在していたので
連想配列で値をセットしてやってます。

あとダミーデータには論理削除されたユーザやデータを含めるとデバッグしやすいのでwithTrashedを噛ませてます。

<?php

use Illuminate\Database\Seeder;

use App\Shop;
use App\User;

class ShopSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Shop::truncate();
        DB::table('shop_user')->truncate();

        $faker = \Faker\Factory::create('ja_JP');

        $users = User::withTrashed()->pluck('id')->toArray();

        factory(Shop::class, 20)->create()->each(function ($shop) use ($faker, $users) {
                        // ランダムなアイテム数のuserのidの配列を作る。
            $arr = $faker->randomElements($users); 
            $data = [];
                        // pivotテーブルの更新したいカラムの値をセット
            foreach ($arr as $val) {
                $user_id = $faker->randomElement(\App\User::withTrashed()->pluck('id')->toArray());
                $data[$val] = [
                    'created_by' => $user_id,
                    'created_at' => $faker->dateTimeThisYear(),
                ];
            }
                        // あとはsyncするだけ!!
            $shop->users()->sync($data);
        });
    }
}

感想

factoryでダミーデータ作るの楽しい。癒やし。