Illuminate\View\ViewExceptionのエラーが発生して画面遷移ができなくなる問題

# はじめに

laravelのバージョンを5.8から6.xにアップデートした後、なぜか画面遷移ができなくなりました。
その原因がなかなかわからず手こずったので、メモを残しておきます。

## 環境

ubuntu 18.04
php 7.4.29

```composer.json
{
    "require": {
        "php": "^7.4.29",
        "bensampo/laravel-enum": "^1.23",
        "fideloper/proxy": "^4.0",
        "google/apiclient": "^2.0",
        "guzzlehttp/guzzle": "^6.3",
        "intervention/image": "^2.5",
        "laravel/framework": "^6.0",
        "laravel/tinker": "^1.0",
        "laravelcollective/html": "^6.0",
        "phpoffice/phpspreadsheet": "^1.10"
    },
}
```

## エラー内容

普通に画面遷移をしていると、遷移できる画面とできない画面があることが判明しました。
遷移できないときに画面に表示されたエラーはこちらです。

```{project_dir}/vendor/laravel/framework/src/Illuminate/Routing/Exceptions/UrlGenerationException.php
<?php
 
namespace Illuminate\Routing\Exceptions;
 
use Exception;
 
class UrlGenerationException extends Exception
{
    /**
     * Create a new exception for missing route parameters.
     *
     * @param  \Illuminate\Routing\Route  $route
     * @return static
     */
    public static function forMissingParameters($route)
    {
        return new static("Missing required parameters for [Route: {$route->getName()}] [URI: {$route->uri()}].");
    }
}
```

エラーメッセージを見ると、routes/web.phpのnameがuser.editのルーティングでパラメータが足りないと言われてますね。

```
Illuminate \ View \ ViewException (E_ERROR)
Missing required parameters for [Route: user.edit] [URI: {language}/user/{id}]. (View: {project_dir}/resources/views/common/user.blade.php) (View: {project_dir}/resources/views/common/user.blade.php) (View: {project_dir}/resources/views/common/user.blade.php) (View: {project_dir}/resources/views/common/user.blade.php)
```

ひとまず、ログに出ているbladeファイルを見てみます。

```{project_dir}/resources/views/common/user.blade.php
    :
    <a href="{{route('user.edit', ['lang' => app()->getLocale(), 'id' => $user->Id])>
    :
```

```{project_dir}/routes/web.php
    :
    Route::get('{language}/user/{id}', 'UserController@updateUser')->name('user.edit');
    :
```

結論から言うと、ここで第二引数のパラメータの配列の要素が **2つ以上** の時にkeyが一致していないことが原因でした。ここでは、user.blade.phpの`'lang'`を`'language'`に直せばいいということです。

今回の場合、第二引数の配列内に入れるべきパラメータの数は足りていました。それでも足りないと怒られていたのは、`'language'`というkeyが配列内にないと判定されたからだったようですね。

また、下記の一つだけのパラメータの場合に、第二引数を配列にしていないでvalueだけを入れるとこれは問題なく遷移できてしまうので、遷移できる画面とできない画面があったようです。。

```diff_php
    :
    {{ 一つだけのパラメータの場合 }}
-   <a href="{{route('user.list', app()->getLocale())>
+   <a href="{{route('user.list', ['language' => app()->getLocale()])>
        
    {{ 第二引数の配列の要素が key => value になっていない場合 }}
-   <a href="{{route('user.edit', [app()->getLocale(), 1])>
+   <a href="{{route('user.edit', ['language' => app()->getLocale(), 'id' => 1])>
    :
```

## 最後に

公式ドキュメントの6.xへのアップデート時にチェックすべき変更点として今回の内容の記述を見つけることができていません。時間があるときにまた探してみます。laravelのアップデート作業はまだまだ続くのでこんな感じのエラーが起きたら記録していこうと思います。

## おまけ

valueにNULLや空文字を設定することができないようなので、何かしらの値を設定する必要があるようです。
※パラメータはあくまで例です。

```diff_php
    :
    {{ NULL }}
-   <a href="{{route('student.list', ['language' => app()->getLocale(), 'search' => null])>
+   <a href="{{route('student.list', ['language' => app()->getLocale(), 'search' => 'none'])>
        
    {{ 空文字 }}
-   <a href="{{route('parent.edit', ['language' => app()->getLocale(), 'name' => ''])>
+   <a href="{{route('parent.edit', ['language' => app()->getLocale(), 'name' => $parenet->Name])>
    :
```

もし、任意のパラメータで設定しないこともあるのであれば、routes/web.phpで、パラメータに?を付けておくとよさそうです。?を付ければ、NULLを設定してもエラーにはなりませんでした。詳しくは参考にさせてもらった記事を見てください。

```{project_dir}/routes/web.php
    :
    Route::get('{language}/user/{id?}', 'UserController@updateUser')->name('user.edit');
    :
```

```{project_dir}/resources/views/common/user.blade.php
    :
    <a href="{{route('user.edit', ['lang' => app()->getLocale(), 'id' => null])>
    :
```

## 参考

https://stackoverflow.com/questions/59489352/error-empty-parameters-route-helper-function-in-laravel-6

https://prograshi.com/framework/laravel/route-optional-parameter/