バージョン情報
- PHP 7.4.2
- Laravel 6.2
実現したいこと
index.html
<input type="radio" name="type" value="A"><label>A</label>
<input type="radio" name="type" value="B"><label>B</label>
<br>
<input type="text" name="text">
- Aが選択されている時は、textが整数であること
- Bが選択されている時は、textが文字列であること
- type, textは必ず入力されていること
こんなバリデーションをしたい。
結論
PostTextRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
class PostTextRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'type' => 'required',
'text' => 'required'
];
}
public function withValidator(Validator $validator)
{
$validator->sometimes('text', 'required | integer', function ($input) {
return $input->type === 'A';
});
$validator->sometimes('text', 'required | string', function ($input) {
return $input->type === 'B';
});
}
}
重要なところ
public function withValidator(Validator $validator)
{
$validator->sometimes('text', 'required | integer', function ($input) {
return $input->type === 'A';
});
$validator->sometimes('text', 'required | string', function ($input) {
return $input->type === 'B';
});
}
解説
元のコード
元々はこんな感じの記述でした。
TextController.php
public function post(Request $request)
{
// バリデーションルールの配列を呼び出す
$validation_rules = $this->rules();
// typeがAかBかによってバリデーションを追加する
if ($request->input('type') === 'A') {
$validation_rules['text'] .= '|integer';
} elseif ($request->input('type') === 'B') {
$validation_rules['text'] .= '|string';
}
// バリデーション実行
$request->validate($validation_rules);
// postの処理...
}
protected function rules()
{
return [
'text' => 'requied',
'type' => 'requied'
];
}
これでも期待通りの動きはしてくれるけど、Controllerに全部書いちゃってるし、if文でバリデーションを追加するとかなんかダサい。
withValidator()というのを使うといい感じにできるらしい。
書き方としては、
public function withValidator(Validator $validator)
{
$validator->sometimes('バリデーションを行うフィールド', 'バリデーション | バリデーション', function ($input) {
return バリデーションをする条件;
});
}
なので、今回のパターンに当てはめると、
PostTextRequest.php
public function withValidator(Validator $validator)
{
// textが整数かどうかのバリデーションを追加したい
$validator->sometimes('text', 'required | integer', function ($input) {
// typeがAだった時に
return $input->type === 'A';
});
// textが文字列かどうかのバリデーションを追加したい
$validator->sometimes('text', 'required | string', function ($input) {
// typeがBだった時に
return $input->type === 'B';
});
}
TextController.php
public function post(PostTextRequest $request)
{
// postの処理...
}
これでControllerはスッキリするし、スマートに書ける(気がする)。
ご指摘、アドバイスお待ちしております。