Laravelのバリデーションにはシンタックスシュガーが多い。本記事で、まとめようと思う。
表現は様々だが、ほぼ全部『バリデーションルールをどこに置くか』の違いである。
つまり、どの書き方でも最終的には「ルール配列」を渡しているだけである。
[
'id' => 'required|unique:product_table,id',
'name' => 'required|string|max:60',
]
違うのは、
- どこに置くか
- 誰が validate() を呼ぶか
- 再利用しやすいか
だけ。
① -A:コントローラに連想配列を直書き
public function store(Request $request)
{
$request->validate([
'id' => 'required|unique:product_table,id',
'name' => 'required|string|max:60',
]);
// バリデーション通過後の処理
}
validate()の第1引数に連想配列を渡してやる方法。
ちなみに第2引数にエラーメッセージを与えたりできる。ただバリデーションだけ、メッセージはいらないなら第2引数もいらない。
$requestオブジェクトの中に入った値(HTMLから受け取った値)を、連想配列に書かれたルールに従ってバリデーションする。
引数となる連想配列について
=>の左側には、.blade.phpでsubmitしたinputのname = 属性値で指定した属性値を
=>の右側には、バリデーション条件を書く。
① -B:ルールを静的プロパティに切り出す
// Item.php
class Item
{
public static $rules = [
'id' => 'required|unique:product_table,id',
'name' => 'required|string|max:60',
];
}
あらかじめ、条件となる連想配列を、静的プロパティとして作っておく。
呼び出す時、インスタンス化の必要を無くせるようにpublic staticで宣言しておく。
// ItemController.php
public function store(Request $request)
{
$request->validate(Item::$rules);
}
public function update(Request $request, $id)
{
$request->validate(Item::$rules); // 使い回せる!
}
そしてコントローラ側で、その連想配列を与えるだけ。
利点としては一度作ったルールを使い回せること。
ただし弱点として、staticでは動的な処理が行えないため、一箇所でも違うルールを適応したいときなどには不便。たとえば、
「新規レコード作成処理時には必要だったが更新処理時はidのバリデーションは必要ない」
みたいなときは、本来ならif分で分岐させたいものだが、あくまでただの連想配列なので動的処理を書き込めない。
① -C : ルールを配列で返すメソッドとして書く
public function store(Request $request)
{
$request->validate($this->rules()); // メソッドの戻り値を渡す
}
// コントローラ内に専用メソッドを作る
private function rules(): array
{
return [
'id' => 'required|unique:product_table,id',
'name' => 'required|string|max:60',
];
}
こちらなら動的処理を書くことが出来る。If分岐に引っかかった場合はruleを発動みたいな。
上記の例では、何の処理もせず、ただ連想配列を戻り値に指定している。
② FormRequestクラスに分離する
// app/Http/Requests/StoreItemRequest.php(Requests下ならなんでもいい)
class StoreItemRequest extends FormRequest
{
// このリクエストを実行する権限があるか(とりあえずtrueでOK)
public function authorize(): bool
{
return true;
}
// バリデーションルールを返す
public function rules(): array
{
return [
'id' => 'required|unique:product_table,id',
'name' => 'required|string|max:60',
];
}
}
FormRequestはRequestクラスの子クラス。
// ItemController.php
// 引数の型をFormRequestのクラス名に変えるだけ!
public function store(StoreItemRequest $request)
{
// コントローラに届いた時点でバリデーション済み
// validate()を呼ぶ必要すらない
}
一番重要な理解
validate()をLaravelが勝手に実行する。
③ Validatorファサード
Validatorファサードを直接使う方法
use Illuminate\Support\Facades\Validator;
$validator = Validator::make(
$request->all(),
[
'id'=>'required'
]
);
if ($validator->fails()) {
return back();
}
バリデーション失敗時の挙動を細かく自分で制御したい上級者向けの書き方
Validator::make()
↑ 元祖
$request->validate()
↑ 短縮版
FormRequest
↑ 自動実行版