Laravelのバリデーションでエラー時の遷移先を制御する

## 問題
- `Laravel`のバリデーションでエラーになった際、入力時のページに戻らない
- `Laravel`のバリデーションでエラーになった際に入力時のページへ戻る際、値は保持されない

## 原因
**`Laravel`でバリデーションを適用した際、エラー発生時に入寮時の画面などに戻る際、`GET`メソッドで遷移されるから**

自分は`Request`の`validate`メソッドを利用し、バリデーションを適用していたため、ルールやエラーメッセージなどの設定はできても、その後の制御ができておらず、冒頭のような問題が発生していた。
[バリデーション 5.5 Laravel](https://readouble.com/laravel/5.5/ja/validation.html)を見ると、`Request`以外にもバリデーションを設定できる方法があったので、それを試してみたら問題が解決したので、その方法を記載する。

## 解決策

**`validator`を利用する**

### validator

`validator`はコントローラに直接記入して利用する。
基本となるのはこの形。

```app/Http/Controllers/SampleController.php
use Validator;

class SampleController extends Controller
{
    public function sample(Request $request)
    {
        $validator = Validator::make($request->all(), [
                //バリデーションルールの記入
            ],
            [
                //エラーメッセージの記入
            ]);

        if ($validator->fails()) {
            return redirect('home')
                        ->withErrors($validator)
                        ->withInput();
            //エラー時の処理
        }
        //バリデーションが通った時の処理
    }
}
```

**`Validator::make`**で`Request`の`Validate`メソッドと同じように、**バリデーションルールやエラーメッセージを指定する。**
`Validator::make`で宣言したバリデーションルールを満たさなかった場合、**`$validator->fails() {}`**が実行される。

- **`redirect`**: 遷移先の指定
- **`withErrors($validator)`**: 遷移先に`$validator`を渡す。
- **`withInput()`**: 遷移先に`Input`があり、渡したい値があれば、ここに指定。

**`Validator`**を使ってリダイレクト先を指定することで、遷移先ページの指定は解決しそう。
ちなみに、リダイレクト先の指定は`routes\web.php`の**`name()`**で指定した値も指定できる。

```routes\web.php
Route::get('/home', 'HomeController@index')->name('home');
```

### Validatorのカスタマイズ

`情報編集画面` →　`情報編集確認画面` → `編集完了画面`みたいな流れで`Laravel`のプロジェクトを作成していたとする。
その際、先程の`redirect()`だと渡せる情報に限界がある場合などが考えられる。
しかし、**`$validator->fails() {}`**で指定できるのは`redirect()`だけではない。
その例を以下に記載する。

```app/Http/Controllers/EditCheckController.php
use Validator;

class EditCheckController extends Controller
{
    public function sample(Request $request)
    {
        $validator = Validator::make($request->all(), [
                'name' => 'required|max:20',
                'email' => 'required|email',
                'body' => 'required',
                'delete_flag' => 'boolean',
                //バリデーションルールの記入
            ],
            [
                'name.required' => '名前を入力してください。',
                'name.max' => '名前は20字以内で入力してください。',
                'email.required' => 'Eメールを入力してください。',
                'email.email' => 'Eメールはメールアドレス形式で入力してください。',
                'body.required' => '本文を入力してください。',
                'delete_flag.boolean'  => '0か1を入力してください。',
                //エラーメッセージの記入
            ]);

        if ($validator->fails()) {
            $edit_id = $request -> input('edit_id');
            $name = $request -> input('edit_name');
            $email = $request -> input('edit_email');
            $body = $request -> input('edit_body');
            $delete_flag = $request -> input('edit_delete_flag');
            $edit_data = User::where('id', $edit_id) -> first();
            $edit = array(
                'id' => $edit_id,
                'name' => $name,
                'email' => $email,
                'works_id' => $body,
                'created_at' => $edit_data['created_at'],
                'updated_at' => $edit_data['updated_at'],
                'delete_flag' => $edit_delete_flag
            );
            $back_url = "location.href='/home'";
            return view('edit',['User' => $edit, 'Back' => $back_url])
                -> withErrors($validator);
            //エラー時の処理
        }
        //バリデーションが通った時の処理
    }
}
```

まるでひとつのコントローラーの処理のようになっているが、このような書き方もできる。
`view()`を指定した書き方によって、`GET`メソッド以外による情報を保持してのページ遷移が可能となった。

## エラー時における入力値の保持

`redirect()`以外によるページ遷移と値の保持の仕方を紹介したが、なら`redirect()`の際はどうやって値を保持すれば良いのか。
`withInput()`を使用するのも一つの手だが、`Laravel`では**oldヘルパ**というものが使用できる。
使い方は`~.blade.php`の`<Input>`などの`value`に**`{{ old('name属性') }}`**を記入するだけ。

また、oldヘルパでは初期値も設定できる。
データベースの値を初期値にしたい場合は第二引数にその値を設定する。

```sample.blade.php
<td><input type="text" name="edit_text" value="{{ old('edit_text', $db->text) }}" ></td>
```

## 参考文献

- [バリデーション 5.5 Laravel](https://readouble.com/laravel/5.5/ja/validation.html)
- [Laravelのredirectでrouteを指定してパラメータも渡したい時 | Awesome Blog](https://awesome-linus.com/2019/05/09/redirect-route-add-parameter/)
- [【Laravelメモ】バリデーションエラー時の入力フォームの値を保持するoldヘルパの使い方 | オノログ](https://naoya-ono.com/blog/laravel-old-helper/)