🍜

Laravel (Laravel8)のSeederでDBファザードを使わずにユーザー属性を一部固定したいとき

3 min read

Laravel8 以前では確認してません

環境

  • macOS Catalina
  • PHP 7.3
  • Laravel 8.1.2

ユーザーの属性を固定したい!!

ユーザーのFactoryを生成し、Fakerを使ってランダムで生成するように書いたが、テスト用で一部のユーザーだけはメールアドレスや名前、権限を固定したい場合があるが、DBファザードを使ってわざわざ作ったりしていた。

UserFactory.php
<?php

namespace Database\Factories;

use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class UserFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = User::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'first_name' => $this->faker->firstName, // 名前をランダム生成
            'last_name' => $this->faker->lastName, // 名前をランダム生成
            'sex' => $this->faker->numberBetween(0, 2), // 性別をランダム生成 0: 男, 1: 女 2: その他
            'privilege' => $this->faker->numberBetween(0, 2), // 権限をランダム生成 0: 一般, 1: 管理者
            'email' => $this->faker->unique()->safeEmail,
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
}
DatabaseSeeder.php
DBファザードを使って生成しまっていて不自然なDatabaseSeeder

<?php

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\QueryException;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([ 
	// DBファザードを利用してテスト用のユーザーを生成している
            'first_name' => 'アドミン',
            'last_name' => 'ララベル',
            'sex' => 2, // 2は性別その他
            'privilege' => 1, // 1は管理者権限
            'email' => 'laravel-a@example.com',
            'password' => Hash::make('password'),
            'remember_token' => Str::random(10),
        ]);

	// ランダムユーザを生成
        User::factory(50)->create();
    }
}

Factoryの属性のオーバーライドができる。

Laravel8 ReaDouble

モデルのデフォルト値をオーバーライドしたい場合は、makeメソッドに配列で値を渡してください。指定した値のみ置き換わり、残りの値はファクトリで指定したデフォルト値のまま残ります。

つまりSeederの値をオーバーライドして好きな値に書き換えることが出来るというわけである。

DatabaseSeeder.php
DBファザードを使って生成しまっているBad Pattern

<?php

namespace Database\Seeders;

use App\Models\User;
use Illuminate\Database\QueryException;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        User::factory()->make([
	// 値のオーバーライド
            'first_name' => 'アドミン',
            'last_name' => 'ララベル',
            'sex' => 2, // 2は性別その他
            'privilege' => 1, // 1は管理者権限
            'email' => 'laravel-a@example.com',
            'password' => Hash::make('password'),
            'remember_token' => Str::random(10),
        ])->save(); // save忘れずに!!

	// ランダムユーザを生成
        User::factory(50)->make([
	    'sex' => 0,
	]);
    }
}