Laravel 404 Not Foundエラーはルーティング順に原因があった
エラー内容
ルーティングはあっているのに、なぜか[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