Laravelでバリデーションを通過させた後にバリデーションを行う方法としてwithValidatorがあるみたいだけど、どうやって書けばいいんだろう….
こんな疑問を解決します。
バリデーションを通過させた後にバリデーションを行うってなんだかイメージつかないと思いますよね。
この記事ではwithValidatorを使って以下のようなバリデーションを実装します。
①まずは、通常のバリデーションを行う(必須とか数字で入力とか)
②上記のバリデーションが全て通った時に、以下のバリデーションを自分で作る
※この記事では、本の最低価格>本の最高価格というありえないパターンをバリデーションさせます。
この場合、ロジックが少し複雑になるので、Laravelで用意されているrequiredなどの簡単なバリデーションを通過させた後に、自分で作ったwithValidatorでバリデーションをしよう!という内容です。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
動作確認・前提
動作確認したのは以下の環境です。
Docker 20.10.7
PHP 7.4.22
Laravel 8.53.1
mySQL 5.7
データベースのツール phpmyadmin
前提として、フォームリクエストでバリデーションをかける人が対象です。以下の記事でバリデーションの解説しているので合わせてチェックしてください。
withValidatorを使ったバリデーションの全体像
まずは結論として、全体像のコードになります。
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BookRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
$validate = [];
$validate += [
'book_name' => [
'required',
'max:10',
],
'book_number' => [
'required',
'numeric',
'digits:2',
'between:1,90'
],
'book_min_price' => [
'required',
'numeric',
'integer',
'min:0',
],
'book_max_price' => [
'required',
'numeric',
'integer',
'min:0',
],
];
return $validate;
}
/**
* 上記のバリデーション通過後に以下のバリデーションを検証
*/
public function withValidator($validator)
{
// 入力された本の最低価格
$input_min_price = $this->input('book_min_price');
// 入力された本の最高価格
$input_max_price = $this->input('book_max_price');
$validator->after(function ($validator) use($input_min_price, $input_max_price) {
// 本の最低価格と本の最高価格がどちらも入力されていれば、以下の処理を実行
if(isset($input_min_price) && isset($input_max_price)) {
// 本の最低価格が本の最高価格よりも値段が高い場合
if($input_min_price > $input_max_price) {
$validator->errors()->add('book_min_price', '本の最低価格は本の最高価格よりも価格は低くしてください。');
}
// 本の最高価格が本の最低価格を下回る
if($input_max_price < $input_min_price) {
$validator->errors()->add('book_max_price', '本の最高価格は本の最低価格よりも価格は高くしてください。');
}
}
});
}
}
このように通常のバリデーションを行った後に、withValidatorを使って、さらにバリデーションをさせます。
通常のバリデーション
まずは、最低限のバリデーションとして以下を実装させます。
'book_min_price' => [
'required',
'numeric',
'integer',
'min:0',
],
'book_max_price' => [
'required',
'numeric',
'integer',
'min:0',
],
入力必須、数字以外はNG、最低入力0以上としました。
こちらのバリデーションが通過したら、本題のバリデーションを実行させます。
withValidatorを使ってバリデーション
withValidatorを使って、バリデーションするにはいろいろな書き方がありますが、シンプルに今回は書きました。
/**
* 上記のバリデーション通過後に以下のバリデーションを検証
*/
public function withValidator($validator)
{
// 入力された本の最低価格
$input_min_price = $this->input('book_min_price');
// 入力された本の最高価格
$input_max_price = $this->input('book_max_price');
$validator->after(function ($validator) use(使う変数を書く) {
});
}
まずは、入力した本の最低価格と最高価格を取得します。
そして、上記のように’$validator->after’のように書いていき、use(ロジックないで使う変数を全て記述)とします。
useに使いたい変数を書かないと、’$validator->after’のロジック内で変数を使えないので注意です。
isset($input_min_price) && isset($input_max_price)
これは本の最低価格と本の最高価格どちらも入力されているか判定しています。
どちらか一方が入力されていなければ、そもそもこのバリデーションは意味ないからです。
$validator->errors()->add('nameの値', 'エラーメッセージ');
$validator->errors()->add('book_min_price', '本の最低価格は本の最高価格よりも価格は低くしてください。');
エラーがあった時の処理を書きます。
/**
* 上記のバリデーション通過後に以下のバリデーションを検証
*/
public function withValidator($validator)
{
// 入力された本の最低価格
$input_min_price = $this->input('book_min_price');
// 入力された本の最高価格
$input_max_price = $this->input('book_max_price');
$validator->after(function ($validator) use($input_min_price, $input_max_price) {
// 本の最低価格と本の最高価格がどちらも入力されていれば、以下の処理を実行
if(isset($input_min_price) && isset($input_max_price)) {
// 本の最低価格が本の最高価格よりも値段が高い場合
if($input_min_price > $input_max_price) {
$validator->errors()->add('book_min_price', '本の最低価格は本の最高価格よりも価格は低くしてください。');
}
// 本の最高価格が本の最低価格を下回る
if($input_max_price < $input_min_price) {
$validator->errors()->add('book_max_price', '本の最高価格は本の最低価格よりも価格は高くしてください。');
}
}
});
}
‘$validator->after’とuseに変数を書くこと、’$validator->errors()->add’がわかれば、理解できるでしょう。
これでLaravelでwithValidatorを使って、バリデーション通過後にバリデーションをする実装ができました。
【まとめ】withValidatorを使い、バリデーション後にバリデーションをする
今回は通常のバリデーション通過後に少し複雑なバリデーションを実行する方法について解説しました。
withValidatorを使って、さまざまなバリデーションを実装してみてくださいね!
このブログでは、他にも実務で役立つLaravelの記事を書いているので、興味があれば合わせてチェックよろしくお願いします。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント