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

が使えます。

メルマガ購読の申し込みはこちらから。

By hikaru