概要
たとえば登録済みユーザーの情報(ユーザー名、メールアドレスなど)を編集・更新することを考える。
メールアドレスをログインIDとしている場合、登録時にはアドレスにunique
のバリデーションルールを適用している。
ユーザー情報を編集する場合もメールアドレスには同様の制約をかけるが、アドレスを変更せずに他の項目を変更しようとしたとき、「既にデータベース上にアドレスが存在している」のでunique
に対するバリデーションエラーとなる。
ここでは、その回避方法を整理する。
フォームリクエストの準備
作成
編集用のビューは別に作成済みで、ルーティングも設定されているとして、以下の様にフォームリクエストを作成したとする。
1 2 |
$ php artisan make:request UserProfileRequest Request created successfully. |
編集
フォームリクエストの実装の際、単にunique
制約とする場合は以下の様になる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class UserProfileRequest extends FormRequest { public function authorize() { return true; } public function rules() { return [ 'name' => ['required', 'string', 'max:255'], 'email' => [ 'required', 'string', 'email', 'max:255', 'unique:users', ], ]; } } |
バリデーションの適用
アクションの引数において、メソッドインジェクションでフォームリクエストを指定。
1 2 3 4 5 6 7 8 9 10 11 12 |
<?php .... use \App\Http\Requests\UserProfileRequest; class UserController extends Controller { .... public function update(UserProfileRequest $request, User $user) { return 'update ' . $user->name; } } |
ここでユーザー名を空白、メールアドレスは登録済みの元の値でバリデーションが行われると、エラーは以下の様になる。
1 2 3 |
The name field is required. The email has already been taken. |
uniqueルールの除外
unique
のルールを課しながら、特定のデータについてこれを除外するために、以下の構文が使える。
Rule::unique('テーブル名')->ignore($this->モデル->id)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class UserProfileRequest extends FormRequest { .... public function rules() { return [ 'name' => ['required', 'string', 'max:255'], 'email' => [ 'required', 'string', 'email', 'max:255', Rule::unique('users')->ignore($this->user->id), ], ]; } } |
以下、バリエーション。
Request::unique('users')
だけだと、'unique:users'
と同じ- これにメソッドチェーンで
ignore($this->user->id)
を付けると、ルートパラメーターの値をとってくる。 ignore($this->user)
と直接オブジェクトで指定しても結果は同じ。
このようにすることで、自身のメールアドレスに関しては同じ内容が許容される。