Laravel のフォームリクエストの使い方
Laravel のバリデーション機能で、ちょっと複雑な処理をしようとする場合には、コントローラに直接記述するよりも、フォームリクエストを使ったほうが見やすくなります。このフォームリクエスト内の記述について、ドキュメントにもそれほど詳しく書いていないですし、先達の情報が古くて使えなかったりしたので、ここで整理してみたいと思います。
バリデーションの前に入力値を加工するなら prepareForValidation
フォームからの入力値を加工することって、割とニーズがあると思います。例えば、全角で入力された電話番号やメールアドレスを半角に変換するような場合とか。このようなときには、prepareForValidation() を利用します。
protected function prepareForValidation()
{
$this->merge([
'mail' => mb_convert_kana($this->mail, 'as'),
'tel' => mb_convert_kana($this->tel, 'as'),
]);
}
上記の例では、入力値を加工して置き換えていますが、新しいデータを作成することもできます。例えば、入力値を API に送って、その返り値をバリデートするような場合に使えます。
public function rule()
{
return [
'result' => [
'required',
function ($attribute, $value, $fail) {
if ($value === 'failed') {
$fail('Test is failed.');
}
},
],
];
}
protected function prepareForValidation()
{
$json = file_get_contents('https://api.example.com/?param=' . $this->param);
$data = json_decode($json, true);
$this->merge([
'result' => $data['result'],
]);
}
例えばこんな感じ。result の値をバリデートして有効性をチェックしています。
通常のバリデーションルールで対応できないときは withValidator
“選択肢で「その他」を選んだときは、理由を必須入力にする” みたいなバリデーションルールは、通常のバリデーションルールでは対応できませんが、withValidator を使うことで可能になります。
public function withValidator(Validator $validator)
{
$validator->sometimes('reason_detail', ['required'], function ($input) {
return $input->reason == 'other';
});
}
バリデーション後にデータを加工したいときは passedValidation
最初に紹介した prepareForValidation とは逆に(?)、バリデーション後にデータを加工したいときは passedValidation を使います。ドキュメントに記載がないのですが、こんな感じで使います。
public function rules()
{
return [
'year' => ['required', 'integer', 'between:1900,'.date('Y')],
'month' => ['required', 'integer', 'between:1,12'],
'day' => ['required', 'integer', 'between:1,31'],
]
}
public function passedValidation()
{
$date = Carbon::create($this->input('year'), $this->input('month'), $this->input('day'));
$this->merge([
'date' => $date,
]);
}
passedValidation は、$request->input の内容をバリデーション後に加工しているので、加工後のデータは $request->validated() では取得できないということが注意点です。そのため、コントローラ側では、こんな感じで受け取ります。
public function confirm(TestRequest $request)
{
$data = $request->validated();
$data['bd'] = $request->input('bd');
return view('confirm', compact('data'));
}
ディスカッション
コメント一覧
まだ、コメントがありません