Laravel : FormRequestクラスを使ってValidation(MyMemo)

みなさんこんにちは
[ジーズアカデミー主席講師 山崎ですm(_ _)m](https://gsacademy.jp/mentor/)
今回はLaravleのValidation「FormRequest」についてMemoしておきます。

##LaravleのValidation「FormRequest」を使用してみる

###前提条件

 - LaravelでCRUDを作成した経験がある人
 - Laravelの基本を理解している人
 - 記事内容的には、LaravelのValidationをFormRequestを使う場合の***自分メモ***です。
 - Laravel 5.7(確認した環境、多分5.5でもOKなはず） 
 - PHP 7.1.20(確認した環境)

###【FormRequestとは？】
ValidationをControllerのMethodから切り離し、Validation専用のファイルを作り処理をさせます。
これにより、Controllerの処理記述量を減らすことになり、更にValidationの処理も別のファイルで管理することになるので、各々の処理がシンプルに記述することが可能になります。

---
###【 例）ControllerでのValidation処理 】
```php:App\Http\Controllers\BooksController.php
...
class BooksController extends Controller
{
    public function store( Request $request ){

        //------------------------------------------------------------------
        //*** Validation：[Start] ***
        //------------------------------------------------------------------
        //バリデーションルールを設定
        $validator = Validator::make($request->all(), [
                'item_name' => 'required|min:3|max:255',
                'item_number' => 'required|min:1|max:3',
                'item_amount' => 'required|max:6',
                'published' => 'required',
        ]);
        //バリデーションルールにでエラーの場合 
        if ($validator->fails()) {
                return redirect('/')->withInput()->withErrors($validator);
        }
        //------------------------------------------------------------------
        //*** Validation：[End] ***
        //------------------------------------------------------------------


        // 本作成処理...
...
```
---

###【 例）FormRequestでValidation処理 】

Validationルールにてエラーがある場合は、以下記述していましたが***必要がなくなります***。

```php:App\Http\Controllers\BooksController.php
        //バリデーションルールにでエラーの場合 
        if ($validator->fails()) {
                return redirect('/')->withInput()->withErrors($validator);
        }
```
#### 1. FormRequestを利用すると以下のことが省略できます
 - redirect先はフォーム送信元に自動で戻ります。 
 - withErrors()は自動でおこなわれます。※$errors変数の作成
 - withInput()は自動でおこなわれます。


#### 2. FormRequestを継承したClass（例：BookInputPost）を作成
ターミナルのコマンドにて以下artisanコマンドで新規ファイルを作成

```cmd:ターミナル
//記法
php artisan make:request ファイル名
//例
php artisan make:request BookInputPost
```
App\Http\Requests\以下に新規ファイルが作成されます。


#### 2. 新規作成した「BookInputPost」ファイルに以下コードを記述
```php:App\Http\Requests\BookInputPost.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;

class BookInputPost extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true; //[ *1.変更：default=false ]
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        //[ *2.追加：Validationルール記述箇所 ]
        return [
            'item_name'   => ['required','min:3','max:10'],
            'item_number' => ['required','max:3'],
        ];
    }
    
    //[ *3.追加：Validationメッセージを設定（省略可） ]
    //function名は必ず「messages」となります。
    public function messages(){
        return [
            'item_name.required'  => '名前を入力してください。',
            'item_name.min'       => '名前は3文字以上でお願いします。',
            'item_name.max'       => '名前は10字以内でお願いします。',
            'item_number.required'=> '冊数を入力してください。',
            'item_number.max'     => '冊数は3字以内でお願いします。',
        ];
    }

}

```
*1. true に変更して許可します（デフォルトではfalse）
*2. Validationルールを連想配列で追加記述します（以下の rules メソッドを記述参考）。
*3. 必須ではありませんが、Validationに該当した項目のエラーメッセージを自分で日本語変更できます（以下 messagesメソッドを参考に）。

---

### 3.Controllerメソッドの引数を変更

- 「 use App\Http\Requests\BookInputPost; 」を追記
- 　public function store(***BookInputPost*** $request)のように引数に***BookInputPost***を指定

 
```php:App\Http\Controllers\BooksController.php
...
use App\Http\Requests\BookInputPost; //*1 FormRequestを使用してValidate

class BooksController extends Controller {

    //---------------------------------------------------------------
    // *store: 引数[Requestクラス → BookInputPostクラス]に変更
    //---------------------------------------------------------------
    public function store( BookInputPost $request ){ //*2 Request → BookInputPost
        $books = new Book;
        $books->item_name = $request->item_name;
        $books->item_number = $request->item_number;
        $books->item_amount = $request->item_amount;
        $books->published = $request->published;
        $books->save();
        return redirect('/');
    }

...
```
実際に試して、動作を確認してみてください。

今回はLaravel5.7で確認しましたが、Laravelドキュメントの5.5でも同様の記載があったので、5.5でも動作すると思われます。

---



##参考にした「Laravel ドキュメント」
https://laravel.com/docs/5.7/validation#form-request-validation

# Youtubeチャンネル
[「遅咲きエンジニア」MicrosoftMVP 山崎](https://www.youtube.com/channel/UCmMFmjhf1BXB1tlLcbkVRrg)
https://www.youtube.com/channel/UCmMFmjhf1BXB1tlLcbkVRrg




以上