【laravel】FormRequestによるバリデーション

# 概要
laravelではいくつかの方法でバリデーションをかけることができます。
そのため一度に投稿するとボリュームが多くなるので複数回に分けます。

[・validateメソッドによるバリデーション]()
[・Validatorによるバリデーション]()
[・ruleオブジェクトによる検証ルールの追加]()
[・バリデーションエラーの表示と日本語化]()

# FormRequestとは
FormRequestはLaravelのファサード（標準クラス）として提供されているRequestファサードを継承し、リクエストパラメータに対するバリデーションルールの定義やユーザーの認証チェックの機能を提供しています。
FormRequestでバリデーションを作成することにより可読性・保守性が上がり、他のクラスでも使用することが出来るようになります。
また、Requestファサードはフォームに関する機能をリクエストに組み込むことが出来るため、コントローラーと処理を明確に分けられるという利点もあります。

# コントローラーとルーティングの作成
例としてFormControllerでバリデーションのコードを記述するため、、コントローラーとルーティングを作成します。

## ルートの定義
FormControllerクラスのpostValidatesメソッドへのルーティングを記述します。

```php:web
Route::post('sample', 'FormController@postValidates');
```

## コントローラーの作成
バリデーションを実行するFormControllerクラスを作成します。
Controllerの作成なので段落だけ付けて詳細は割愛します。

### コマンド
```:コマンド
php artisan make:controller FormController
```

### ディレクトリ構造

```:ディレクトリ
app
├─ Http
|  ├─ Controllers
|  |  ├─ FormController.php
```

### 作成されるファイル

```php:FormController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FormControllerextends Controller
{
    //
}
```

# フォームリクエストの作成
バリデーションを実行するクラスを作成します。
ここではPostRequestという名称で作成します。

## コマンド
手作業でも作成できますがartisanコマンドを利用すれば自動で作成されます。

```:コマンド
php artisan make:request PostRequest
```

## ディレクトリ構造
app\Http内にRequestsフォルダが作成されます。
フォームリクエストは指定がなければ`Requests`内に配置されます。

```:ディレクトリ
app
├─ Http
|  ├─ Requests
|  |  ├─ PostRequest.php
```


## 作成されるファイル
artisanコマンドで作成した場合は以下のような内容が自動で作成されます。
長くなるのでコメント部分は割愛します。

```php:PostRequest
class PostRequest extends FormRequest
{
  public function authorize()
  {
      return false;
  }

  public function rules()
  {
      return [
          //
      ];
  }

```

## フォームリクエストの中身
フォームリクエストはFormRequestクラスを継承して作成され、authorizeメソッドとrulesメソッドが用意されます。
上述しましたが、FormRequestクラスはRequestファサードを継承しており、Requestの機能をベースにフォーム処理に関する機能が追加されています。
authorizeメソッドはbool型で、rulesメソッドはarray型となっています。

### authorize
フォームリクエストの利用が許可されているかどうかを示すメソッドです。
bool型でtrueを返せば許可されていると判断され、falseを返すと許可されていないと判断されます。

### rules
ここに適用させたいバリデーションなどのルールを記述します。


# バリデーションの作成
作成したPostRequestクラスのauthorizeメソッドとrulesメソッド、POST送信時の処理を行うFormControllerクラスの3つを編集することでバリデーションを実行します。

## フォームリクエストの編集
フォームリクエストではauthorizeメソッドとrulesメソッドの両方を記述する必要があります。
上述しましたがauthorizeメソッドはフォームリクエスト利用の許可判定で、rulesは適用させたいバリデーションなどのルールを記述します。

```php:authorize
if ($this->path() == 'sample') {
  return true;
} else {
  return false;
}
```

```php:rules
public function rules()
{
  return [
    'name' => 'required',
    'age' => 'integer | between:0,150',
    'sex' => ['max:1', 'regex:/^[男|女]+$/u'],
  ];
}

// 記述方法：['検証する値'=>'検証ルール1 | 検証ルール2',]
// もしくは、['検証する値'=>['検証ルール1', '検証ルール2'],]
```

### authorize
ここでは`$this->path`を用いてsamlpeへのアクセスのみを許可するという書き方をしています。
全てのパスのアクセスを許可する場合は`return true;`のみの記述で問題ありあません。

```php:authorize
public function authorize()
{
  if ($this->path() == 'sample') {
    return true;
  } else {
    return false;
  }
}
```

### rules
検証ルールの配列をreturnで返しています。
検証ルールは連想配列で['postしてきた値'=>'検証ルール']となっています。

```php:rules
return [
  'name' => 'required',
  'age' => 'integer | between:0,150',
  'sex' => ['max:1', 'regex:/^[男|女]+$/u'],
];
```

## コントローラーの編集
作成したFormControllerクラスにpostValidatesメソッドを作成します。
ポイントは引数のrequestをPostRequestとしていることです。
これでバリデーションが成功すればmsgがビューへ渡されます。

```php:FormController
public function postValidates(PostRequest $request) {
  return view('sample.index',['msg'=>'OK']);
}
```

## エラーメッセージのカスタマイズ
エラーメッセージをカスタマイズするにはFormRequestの`messages`というメソッドをオーバーライドします。
ただし、エラーメッセージは検証ルールごとに設定する必要があるため、エラーメッセージの設定がない検証ルールはデフォルトのエラーメッセージが返されます。

```php:PostRequest 
public function messages(){
  return [
    'name.required' => '名前を入力してください',
    'age.numeric' => '整数で入力してください',
    'age.between' => '0～150で入力してください'
    'sex.regex' => '男か女で入力してください',
  ];
}
```

```:表示例
name（required）：名前を入力してください
age（integer）：整数で入力してください
age（between）：0～150で入力してください
sex（max:1）：The sex may not be greater than 1 characters.
sex（regex:/^[男|女]+$/u）：男か女で入力してください
```

# 参考
[Laravel 6.x バリデーション / フォームリクエストバリデーション]
(https://readouble.com/laravel/6.x/ja/validation.html#form-request-validation)
[Laravel 6.x ファサード]
(https://readouble.com/laravel/6.x/ja/facades.html)
[Laravelのフォームリクエストクラスでバリデーションロジックをコントローラから分離する](https://www.ritolab.com/entry/41)
[Laravelを使ったAPI開発でController内のバリデーションをFormRequestに抽出して幸せになろう]
(https://nakka-k.hatenablog.com/entry/2019/06/04/191906)
[【保存版】バリデーションルールまとめ]
(https://www.wakuwakubank.com/posts/376-laravel-validation/)