Help us understand the problem. What is going on with this article?

【Laravel】更新時のユニークチェックで特定の値は対象外としたいときの対応

More than 1 year has passed since last update.

LaravelでWebアプリを作成していて、バリデーションチェックを行うときに以下の部分でハマりました。

  • emailカラムに登録しようとしている値がUNIQUEかどうか判定したい
  • ただし、更新時に自分のemailと重複するのは許容したい
  • 自分かどうかの判定はidカラムではなく、user_idカラムの値で判定したい

1.前提

  • PHP v7.2.5
  • Laravel v5.5.40

2.解決策

$request->validate([
    # unique:ユニークチェックをしたいテーブル名,ユニークチェックをしたいカラム名,ユニークチェックを除外したい値,ユニークチェックを除外したいカラム名
    'email' => 'unique:users,email,'.$this->me->user_id.',user_id',
]);

IDのカラム名がidであれば、上記の第4引数であるuser_idはなくても上手く動きます。
Laravelのデフォルトではプライマリーキーのカラム名はidとなるため、自動でプライマリーキーがidとして検索が行われるからです。

プライマリーキーのカラム名をidでなくuser_idなど、カスタマイズしている場合には上記のようにプライマリーキーのカラム名を明示しなくてはなりません。

3.理由

Laravelのソースを参照すると以下のようになっています。
第4引数でカラム名を取得してくれる構造になっているので、こちらを利用すればOKということになります。

vender/laravel/framework/src/Illuminate/Validation/Rules/Unique.php
<?php

namespace Illuminate\Validation\Rules;

class Unique
{
    use DatabaseRule;

    /**
     * The ID that should be ignored.
     *
     * @var mixed
     */
    protected $ignore;

    /**
     * The name of the ID column.
     *
     * @var string
     */
    protected $idColumn = 'id';

    /**
     * Ignore the given ID during the unique check.
     *
     * @param  mixed  $id
     * @param  string  $idColumn
     * @return $this
     */
    public function ignore($id, $idColumn = 'id')
    {
        $this->ignore = $id;
        $this->idColumn = $idColumn;

        return $this;
    }

    /**
     * Convert the rule to a validation string.
     *
     * @return string
     */
    public function __toString()
    {
        return rtrim(sprintf('unique:%s,%s,%s,%s,%s',
            $this->table,
            $this->column,
            $this->ignore ? '"'.$this->ignore.'"' : 'NULL',
            $this->idColumn,
            $this->formatWheres()
        ), ',');
    }
}

ソースを読めばしょうもない話なのですが、日本語のドキュメントが意外と見つからなかったので、こちらに残しておきます。

4.参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした