Laravelのedit/updateフォームでvalidationから1レコードだけ除外する
ユーザー情報の登録について、アップデートしたい場合に、登録時に例えばメールアドレスにバリデーションで unique
をつけていた時、アップデート時は、そのメールアドレスはすでにその人のレコードではあるので、ユニークバリデーションから除外したい時ってありますよね。
でも、他の人のメールアドレスとは被らないことをチェックしてほしい。
そういう時は、uniqueルールの引数で、ignore(無視)するレコードを指定することができます。
バリデーションのリクエストファイルの、rulesに以下のルールを追加します。
unique:table,column,except,idColumn
Validation - Laravel - The PHP Framework For Web Artisans
このexcept
というところに、チェックから外したいレコードの id
を入れると良いようです。
実際に、userテーブルのemailカラムを重複させたくない場合、rules
メソッドの中身は、以下のようになります。
$user = $this->route('user'); return [ 'email' => 'unique:users,email,'.$user->id, ];
この時、 $this->route('user')
というところでは何をしているかというと、このリクエストファイルに到達するときのルート(=updateメソッドを呼び出すルート)に含まれているルートパラメータの user
というのを取得しています。
つまり、ルートファイルのなかで、
Route::get('/users/{user}', 'UsersController@show');
とか書いていますよね。
ここでいうところの、 {user}
で指定している文字列のことですね。
Laravelでは、ルートパラメーターに、id
を挿入すると、自動的に、その id
をもつモデル(ここでは User
)を返してくれるので、 $user
には、今アップデートしようとしているユーザーモデルが入るというわけです。
ただ、ルートパラメータに id
以外の何かを入れている場合は、自動でユーザーモデルを取得してはくれないので、
自分で取得する必要があります。
$alias_ = $this->route('user_alias'); $user = User::where('alias', $alias)->firstOrFail();
これで、 $user
には、ユーザーモデルが入ってくれます。
rules
の中に書いている、 $user->id
というのは、取得したユーザーモデルのidをさすので、このレコードは、バリデーションのuniqueルールをチェックする時に除外してくれる、という寸法です。
ちなみに、こちらはバージョン5.3あたりから、新しいカスタムバリデーション的なものを作成する方法に変わってしまったらしいのですが、(記事を読んだのみで、未確認) 以前の書き方の方がシンプルだし、少なくとも2018年7月現在もまだ上記のやり方が通用することを確認しています。
以上。
参考:5.2の公式ドキュメント