- (ある事情で) FormRequest をメソッド・インジェクションで使用せず、Controller 内で
Validator::make()
してバリデータを生成し、ちょっと変わった使い方をした
- その際、バリデーションエラーメッセージ の プレースホルダ に
attributes()
が反映されず、少しハマったので、メモ
ドキュメント
sample
FormRequest
final class HogeRequest extends FormRequest implements HogeRequestInterface
{
public function authorize(): bool
{
return true;
}
public function attributes(): array
{
return [
'dog' => '犬',
'cat' => '猫',
];
}
public function rules(): array
{
return [
'dog' => [
'required',
],
'cat' => [
'required',
],
];
}
public function messages(): array
{
return [
'dog.required' => ':attribute は必須です。', //犬 は必須です
'cat.required' => ':attribute は必須です。', //猫 は必須です
];
}
}
final class HogeController extends Controller
{
// 通常は FormRequest をメソッド・インジェクションして利用
public function __invoke(HogeRequest $request)
{
// FormRequest をメソッド・インジェクションすると、
// バリデーションエラーがあった際に、
// 自動的に元の画面にリダイレクトしてエラーメッセージが表示される
}
}
Controller (これだと attributes()
が効かない)
final class HogeController extends Controller
{
public function __invoke(Request $request)
{
// バリデーション対象のパラメータ
$postParam = $request->all();
// HogeRequest インスタンス作成
$curRequest = new HogeRequest();
// Validator インスタンス作成
$validator = Validator::make(
$postParam,
$curRequest->rules() //HogeRequest インスタンスからバリデーションルールを取得
);
// 特定のリクエストパラメータがバリデーションエラーの場合のみ、元の画面(入力値は保持)にバリデーションエラーメッセージを表示
if ($validator->errors()->has('cat')) {
$errors = new MessageBag();
$errors->add(
'cat',
$validator->errors()->get('cat')[0]
);
return redirect()->route('xxxx')
->withErrors($errors) //エラーメッセージが「cat は必須です」のまま
->withInput();
}
// 〜 略 〜
}
}
Controller (こうすると attributes()
が効く)
final class HogeController extends Controller
{
public function __invoke(Request $request)
{
$postParam = $request->all();
$curRequest = new HogeRequest();
$validator = Validator::make(
$postParam,
$curRequest->rules(),
$curRequest->messages(), //★ココ (HogeRequest インスタンスからエラーメッセージを取得)
$curRequest->attributes() //★ココ (HogeRequest インスタンスから attributes を取得)
);
if ($validator->errors()->has('cat')) {
$errors = new MessageBag();
$errors->add(
'cat',
$validator->errors()->get('cat')[0]
);
return redirect()->route('xxxx')
->withErrors($errors) //エラーメッセージが「猫 は必須です」になった!
->withInput();
}
// 〜 略 〜
}
}
調査メモ
vendor/laravel/framework/src/Illuminate/Validation/Factory.php
を見れば make メソッドの引数がわかった。
/**
* Create a new Validator instance.
*
* @param array $data
* @param array $rules
* @param array $messages
* @param array $customAttributes
* @return \Illuminate\Validation\Validator
*/
public function make(array $data, array $rules, array $messages = [], array $customAttributes = [])
{
$validator = $this->resolve(
$data, $rules, $messages, $customAttributes
);
// The presence verifier is responsible for checking the unique and exists data
// for the validator. It is behind an interface so that multiple versions of
// it may be written besides database. We'll inject it into the validator.
if (! is_null($this->verifier)) {
$validator->setPresenceVerifier($this->verifier);
}
// Next we'll set the IoC container instance of the validator, which is used to
// resolve out class based validator extensions. If it is not set then these
// types of extensions will not be possible on these validation instances.
if (! is_null($this->container)) {
$validator->setContainer($this->container);
}
$this->addExtensions($validator);
return $validator;
}