Laravel バリデーションを設定する ~コントローラ編~

# 目的

- 入力値をDBに保存する際にアプリケーション側でそのデータが要件を満たしているのかをフィルターする仕組みを実装する

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 説明に関する前提の説明

- 下記の方法、またはそれに準ずる方法でLaravelの環境を構築していること。
    - [Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08)
- Laravelのアプリケーションが存在すること。

# 前提情報

- 今回紹介するバリデーションルール以外は公式ドキュメントの「使用可能なバリデーションルール」に記載されている。
    - [https://readouble.com/laravel/6.x/ja/validation.html](https://readouble.com/laravel/6.x/ja/validation.html)

# 説明に関する前提のコード

- 下記のような「ビューでの入力値をDBに格納する処理」が存在する事を前提として説明を行う。

1. ルーティングファイル

    ```web.php
    //入力フォームを表示する
    Route::get('/new', 'ContentController@new');
    //入力値を受け取ってDBに保存する
    Route::post('/create', 'ContentController@create');
    ```
1. コントローラファイル(当該アクション部分のみ記載する)

    ```ContentController.php
    //入力フォームを表示する contentディレクトリのnew.blade.phpを表示する
    public function new() {
        return view('content.new');
    }

    //入力値を受け取ってDBに保存する DBへの格納処理の記載は省略する
    public function create(Request $request) {

        //受け取った値を連想配列に格納
        $notice_info = $request->all();

        //DBへの登録処理
    }
    ```
1. ビューファイル

    ```content/new.blade.php
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
      <form action="/create" method="POST">
        <input type="text" name="input_content">
        <input type="submit" value="送信">
      </form>
    </body>
    </html>
    ```

# 実施方法概要

- コントローラにバリデーションを記載する方法をまとめる。

1. バリデーションルールの設定
1. バリデーション本体の記載
1. 確認

# 実施方法詳細

1. バリデーションルールの設定
    1. 下記のようにコントローラに記載してバリデーションルールを定義する。
    1. バリデーション内容は「空状態での送信をブロックする」ものとする
    1. バリデーションルールに引っかかった場合、`/new`のページ(入力を行って送信ボタンをクリックしたページ)にリダイレクトされるようにする。

        ```ContentController.php
        //入力フォームを表示する contentディレクトリのnew.blade.phpを表示する
        public function new() {
            return view('content.new');
        }

        //入力値を受け取ってDBに保存する DBへの格納処理の記載は省略する
        public function create(Request $request) {
            //バリデーションのルール設定
            $rules = [
                //'ビューのinput要素のnameで指定したキーの名前' => ['バリデーションのルール'],のように記載する、requiredは空の状態での送信をブロックするルールである
                'input_content' => ['required'],
            ];

            //受け取った値を連想配列に格納
            $notice_info = $request->all();

            //DBへの登録処理
        }
        ```
    
1. バリデーション本体の記載
    1. バリデーションの命令を記載する

        ```ContentController.php
        //入力フォームを表示する contentディレクトリのnew.blade.phpを表示する
        public function new() {
            return view('content.new');
        }

        //入力値を受け取ってDBに保存する DBへの格納処理の記載は省略する
        public function create(Request $request) {
            //バリデーションのルール設定
            $rules = [
                //'ビューのinput要素のnameで指定したキーの名前' => ['バリデーションのルール'],のように記載する、requiredは空の状態での送信をブロックするルールである
                'input_content' => ['required'],
            ];

            //下記のように記載してバリデーションを設定する
            //$this->validate(ビューのform要素から送られた値が格納された変数$request, バリデーションルールが格納された変数$rules);のように記載する
            $this->validate($request, $rules);

            //受け取った値を連想配列に格納
            $notice_info = $request->all();

            //DBへの登録処理
        }
        ```
    1. ビューファイルを編集してエラーメッセージを出力する記載を追加する。

    ```content/new.blade.php
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
      <form action="/create" method="POST">
        <!-- 下記を追記する -->
        <!-- バリデーションルールはひとつであるが、複数のエラーメッセージが出力される事を想定してforeach文でエラーを出力する -->
        <!-- 配列$errorsのキー'input_content'にメッセージが格納されているかの分岐 -->
        @if ($errors->has('input_content'))
          <!-- 配列$errorsのキー'input_content'に格納されているメッセージを行っこづつ変数$input_content_errorに格納する -->
          @foreach ($errors->get('input_content') as $input_content_error)
            <!-- 変数$input_content_errorを出力する -->
            <p>{{$input_content_errors}}</p>
            <br>
          @endforeach
        @endif
        <!-- ひとつのエラーメッセージのみ出力したい場合、下記の記載でも可 -->
        <!--
        @if ($errors->has('input_content'))
          <p>{{$errors->first('input_content')}}</p>
        @endif
        -->
        <!-- 上記までを追記する -->
        <input type="text" name="input_content">
        <input type="submit" value="送信">
      </form>
    </body>
    </html>
    ```
1. 確認
    1. `/new`にアクセスし、input要素で表示されている入力ボックスに何も入力せず「送信」ボタンをクリックする。
    1. `/new`が際表示される事を確認する。

# 参考文献

- [https://readouble.com/laravel/6.x/ja/validation.html](https://readouble.com/laravel/6.x/ja/validation.html)