技術日記Laravel4PHP
Laravel 4のエラーメッセージとフォームエラーEdit

Laravel 4では、

Redirect::to()->withErrors()

をすると、自動的にリダイレクト後のビュー内で$errorsに展開されるなど、エラーメッセージは特別な扱いになっている。このエラーメッセージは共通レイアウトなんかで、

@if ($errors->count() > 0)
<ul class="error">
@foreach ($errors as $error)
<li>{{{ $error }}}</li>
@endforeach
@endif

なんて感じに表示するのが普通だろうけど、フォームエラーなんかで、入力欄のそばにエラーメッセージを表示したい場合は、どういうふうに使い分けるといいんだろう。

(エラー表示コードを含む)共通レイアウトは使わず、フォーム表示ビューの方で、

{{ Form::open() }}
{{ Form::label('name') }}
{{ Form::text('name') }}
{{ $errors->first('name', '<p class="error">:message</p>') }}
{{ Form::close() }}

みたいな感じに書くのがいいのか。でもそうなると、(エラーメッセージ表示をしたい)フォームを含むかどうかで、レイアウトファイルを(エラー表示コードを含む物と含まない物で)切り替えることになるのが、あんまり気持ちよくない。

あるいは

[source language="php"] Redirect::to()->with('formErrors', $validator->messages) [/source]

なんて感じで、標準エラーメッセージを使わずに、独自のフラッシュセッションに保存して、

[source language="php"] if (Session::has('formErrors')) { View::share('formErrors', Session::get('formErrors'); } [/source]

とかやる方がいいんだろうか。これはこれでありだろうけど、せっかく標準エラーメッセージ機能があるのに、別でハンドリングするのも今ひとつのような気もする。

標準エラーメッセージを使いつつ、フォームビューの方でエラーメッセージを表示した場合は、何らかの方法でフラグをセットして、レイアウトの方のエラーメッセージを抑止するという方法も考えたんだけど、(コンテンツ)ビューから(レイアウト)ビューにデータを渡す、ほどよい方法が見当たらないんで、ペンディング中。

$errorsの実装クラスであるMessageBagにMessageBag::clear()とかが実装されていれば話が早かったんだけど、MessageBagは値を追加したりマージしたりはできても、削除とかリセットとかはできない模様。

今のところ、独自フラッシュセッションを使う方法が一番ましかなーとは思っているんだけど、もっときれいな方法があるという方、情報をお待ちしております。

追記@2013/07/18)

って話は、Laravel 4のwithErrors()は、レイアウトファイルなどを使って、サイト全体で共通表示するフラッシュメッセージ的なものと捉えた上で書いていたんだけど、なんか違うような気がしてきた。

withErrors()で渡すエラーは、共通フラッシュメッセージ的なものではなく、あくまでも特定機能(ページ)でのエラーを手軽にハンドリングするための入れ物なのか? 共通フラッシュメッセージは、with()とかを使った独自処理として書くべき?

たとえば、Laravel-4-Bootstrap-Starter-Site/app/views/notifications.blade.php at master · andrew13/Laravel-4-Bootstrap-Starter-Siteなんかを見ると、共通フラッシュメッセージ的な物としては、success、warning、error、infoを直接Session::flash()(=with())経由でやりとりして表示し、withErrors()(=$errors)はフォームエラー表示専用として扱っているようだ。

withErrors()はあくまでフォームエラー専用の入れ物であって、フラッシュメッセージとは別物、というのが妥当なアプローチなのかな。なんかフォームエラー専用の代物を、フレームワーク標準で自動的にビュー変数にまで代入しちゃうのは、やり過ぎ感が否めないんだけどなー。

Published At2013-07-17 19:07Updated At2020-01-01 15:40