👌

Laravel 404 Not Foundエラーはルーティング順に原因があった

2022/03/01に公開

エラー内容

ルーティングはあっているのに、なぜか[404 Not Found]とエラーが発生してしまう。

原因

色々、原因はありますが
原因の一つを紹介したいと思います。

僕の場合は「ルーティングの順番」がエラーの原因でした。

これだけだと「?!?!?」となりそうなので、少し深堀して解説していきます。

実例

まず、エラー時のコード配列

Route::get('/users/{userList}', [UserListController::class,'show'])
    ->name('users.show');

Route::get('/users/create', [UserListController::class,'create'])
    ->name('users.create');

まず、前提としてルーティングは「上から順に実行される」という特性を知っておかなければ
なりません。
知らなかった方は、今知れたのでOKです!

つまり、上のコードで
/users/createのリンクが開かれた場合
/users/{userList}が先に実行されます。

さあ、ここからが問題なのです。
{userList}は引数なので、何かしら値が渡されてしまいます。
今回は{userList}と同じ位置に「/create」が存在するため
{userList}にcreteが渡されてしまいます。(ここ重要)

つまり、
1.ModelからuserListカラムにcreateという値が存在しない判定になる
2.userListがcreateである他のカラムも取得できないため、showメソッドを実行したController側でエラーになる

こんな流れで「404 Not Found」が出てしまうんですねえ。。

解決方法

解決としては、ルーティングの順番を変えれば良いのですが
毎度毎度、順番を変えるのって面倒ですよね、
ルーティング追加した時に、またエラー出ちゃいそうだし。

なので、最強メソッドを紹介します。
それは

->where('userList', '[0-9]+');

を追加することです。
「はにゃ?!」となっても大丈夫です。
ちゃんと説明していきます。

->whereとはなんぞや

whereって、英語の関係代名詞で言えば、その前の句を追加説明する時に使用します。
なので、今回で言えば、ルーティングに追加ルールを付与するみたいな感じです!

どんなルールかと言うと
'userList'は'0~9'の数字しか入らないよ。文字とかなら飛ばしてや。
という意味です。

こんな感じでルール設定をしておけば
ルーティングエラーにはならないのです。

まとめ

{引数}で指定するならば
whereで数字限定にしろ。

以上です!

Discussion