LaravelのuniqueのバリデーションでIDを除外する

LaravelのuniqueのバリデーションでIDを除外するLaravel
LaravelのuniqueのバリデーションでIDを除外する

Laravelで重複チェック(unique)を行う際に、IDが同じ場合は重複のチェックを除外したい場合の方法です。

よくあるパターンだと、メールアドレスをユーザーテーブルに保存していて、ログインにアドレスを使っている場合、ユーザー情報を更新する際に、重複チェックに引っかかってしまうパターンが多いかなと思います。

今回は、FormRequestを使っているので、FormRequestに記述する方法を記載します。

FormRequestの記述

Usersテーブルに対してリクエストを行い、重複チェックを行う想定で実装していきます。
artisanコマンドでUserRequestを作成します。

php artisan make:request UserRequest

app/Http/Requests/UserRequest.php に UserRequest.php が作成されるので、UserRequest.phpのrulesメソッドに下記を記述します。

use Illuminate\Validation\Rule;
class UserRequest extends FormRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => ['required', Rule::unique('users')->ignore($this->id)],
        ];
    }
}

ignoreメソッドについて

Rule::uniqueのignoreの内容は、下記のようになります。

Rule::unique({テーブル名またはModel})->ignore({チェックする値}, {カラム名})

テーブルのしては、Modelを指定することも可能なので、以下のような記述も可能です。

        return [
            'email' => ['required', Rule::unique('App\User')->ignore($this->id)],
        ];

Modelを指定した方が、汎用性が高いかもしれませんね。

igonoreメソッドの第二引数は、チェックするカラム名を指定することができます。
例えば、プライマリキーがidではなくserialだった場合、

        return [
            'email' => ['required', Rule::unique('users')->ignore($this->id, 'serial')],
        ];

で、serialカラムでIDの重複チェックを行います。

また、where句など検索条件を指定することも可能です。
deleted_atがnullのもので重複チェックを行う場合、

        return [
            'email' => ['required', Rule::unique('users')->ignore($this->id)->whereNull('deleted_at')],
        ];

のような条件を指定することが可能です。

Controllerでの呼び出し

Controller側でUserRequestを指定します。今回はupdateメソッドに追記していきます。

use App\Http\Requests\UserUpdateRequest;
class UserController extends Controller
{
    /**
     * Update the specified resource in storage.
     *
     * @param  UserRequest  $request
     * @param  int  $id
     * @return JsonResource
     */
    public function update(UserRequest $request, int $id)
    {
    }
}

これで、UserControllerに到達する前に、UserRequestでバリデーション処理が実行され、メールアドレスの重複チェックが行われます。

ユーザー情報のIDの重複チェックについて

今回は、ユーザーのメールアドレスの重複チェックを例に上げましたが、今回の場合だとマイページなどでユーザー情報の更新を行う場合が想定されると思います。
その場合は、すでにユーザーがログイン済みなので、requestのidを取得するより、Auth::id()で取得した方が良いかもしれません

        return [
            'email' => ['required', Rule::unique('users')->ignore(Auth::id())],
        ];
タイトルとURLをコピーしました