1つのページに複数のフォームが存在する場合、エラーの管理が煩雑になりがちです。
そんな時は名前付きエラーバッグを使ってフォーム毎にエラーを分けると管理しやすいです。
煩雑になってしまう例
複数のフォームがある場合にエラー管理が煩雑になる、とはどんな時でしょうか?
例を用いて解説します。
フォームが2つあり、それぞれ別のルートにPOSTされます。
ここでプランナーさんから
「バリデーションエラー発生時に警告文をフォーム毎に文言を変えて表示したい!」
とリクエストが来たとします。つまり、
ユーザ情報フォームに関する何かしらのエラーがあれば以下を表示

そして、会社情報フォームに関する何かしらのエラーがあれば以下を表示

何かしらのエラーがあれば、、、と言う条件はフォームが1つであれば簡単で
@if ($errors->any()) ... 警告文 @endif
とできますが、フォームが複数ある場合はどうすれば良いでしょうか?
sessionに判別用の値をセットする?それともリダイレクト元のルートで判別する?
やり方は色々あると思いますが、名前付きエラーバッグを使うとスマートにできます。
名前付きエラーバッグとは?
その名の通り、エラーバッグに任意の名前を付けたものです。
(ここで言うエラーバッグとは、blade側でエラーを参照する際に使う $errors です)
フォーム毎にエラーバッグの名前を分けて付けることで、
エラーを分けて管理できるようになります。
エラーバッグに名前をつける
エラーバッグに名前を付けるにはバリデーション時にvalidateWithBag()を使用します。
例えば、前項のフォームのバリデーションで以下のようにしています。
ユーザ情報フォーム側では、エラーバッグ名をuserとして第一引数に指定しています。
$validated = $request->validateWithBag(
'user', // ←エラーバッグ名
['name' => 'required'],
['name.required' => '名前を入力してください。']
);
会社情報フォーム側では、エラーバッグ名をcompanyとして指定しています。
$validated = $request->validateWithBag(
'company', // ←エラーバッグ名
['company_name' => 'required'],
['company_name.required' => '会社名を入力してください。']
);
また、withErrors()を使って
リダイレクトにエラーをセットする際は第二引数にエラーバッグ名を指定します。
return back()->withErrors($validator, 'user')->withInput();
名前付きエラーバッグからエラーを参照する
エラーバッグ名の指定ができたので、今度はblade側でエラーを参照してみましょう。
任意の名前のエラーバッグからエラーを参照する際は、
$errors->エラーバッグ名->first(...)などとします。従って、
// ユーザ情報フォームのエラーを取得する場合、
{{ $errors->user->first('name') }}
// 会社情報フォームのエラーを取得する場合、
{{ $errors->company->first('name') }}
// errorディレクティブを使う場合は第二引数にエラーバッグ名を指定
@error('name', 'user')
{{ $message }}
@enderror
また、前項の警告文の様に、ユーザ情報フォームに何かしらのエラーがあるか判別するには
@if ($errors->user->any()) ... @endif
が使えます。
メルマガ購読の申し込みはこちらから。
