LoginSignup
28
23

More than 3 years have passed since last update.

Laravelのルーティング優先度でつまづいた話

Last updated at Posted at 2019-02-18

404エラー発生

以下のルーティング・Controller・Viewを実装したところ/stadium/createにアクセスすることができず、
404エラーが発生しページが存在しないエラーが出ます。(createビューは作成しています。)

web.php
Route::get('/', 'StadiumPostsController@index');
Route::get('/stadium/{id}', 'StadiumPostsController@show');
Route::get('/stadium/{id}/edit', 'StadiumPostsController@edit');
Route::patch('/stadium/{id}', 'StadiumPostsController@update');
Route::post('/stadium', 'StadiumPostsController@store');
Route::get('/stadium/create', 'StadiumPostsController@create');
StadiumPostsController(createメソッドのみ).php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\StadiumPost;

    class StadiumPostsController extends Controller{
         public function create() {
             return view('create');
         }
}
index.blade.php
    <h3>
      <a href="{{ url('/stadium/create') }}">New Stadium</a>
    </h3>

エラー原因

Laravelのルーティング設定では、

上に書かれた設定が優先的に実行される

ということです。

参考
Laravelのルーティングチートシート

なので、web.php/stadium/createが一番下に書かれており、
/stadium/{id}が上にあることで、

  1. idパラメータにcreateという値を受け渡す
  2. Modelからidカラムにcreateという値が存在しない判定になる
  3. idcreateである他のカラムも取得できないため、showメソッドを実行したController側でエラーになる

となってしまいます。

対処方法としては以下の2通りです。

対処方法1:優先度を変更

単純な方法ですが、ルーティングの書く順番を変更すれば対処することができます。
/stadium/{id}を下にして、/stadium/createを上に書くことでエラー回避でき、
ちゃんとController側でcreateメソッドが実行されます。

web.php
Route::get('/', 'StadiumPostsController@index');
Route::get('/stadium/create', 'StadiumPostsController@create'); // 上に移動
Route::get('/stadium/{id}', 'StadiumPostsController@show');// 下に移動
Route::get('/stadium/{id}/edit', 'StadiumPostsController@edit');
Route::patch('/stadium/{id}', 'StadiumPostsController@update');
Route::post('/stadium', 'StadiumPostsController@store');

対処方法2:正規表現で条件分岐

showメソッドを実行するために必要なidパラメータは
正の自然数しか出ないAUTO_INCREMENTになっておりますので、
ルーティングに0-9の数値でしか推移しないよう対処しました。

web.php
Route::get('/', 'StadiumPostsController@index');
Route::get('/stadium/{id}', 'StadiumPostsController@show')->where('id', '[0-9]+'); // 正規表現追加
Route::get('/stadium/{id}/edit', 'StadiumPostsController@edit')->where('id', '[0-9]+');
Route::patch('/stadium/{id}', 'StadiumPostsController@update')->where('id', '[0-9]+');
Route::post('/stadium', 'StadiumPostsController@store');
Route::get('/stadium/create', 'StadiumPostsController@create');
28
23
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
23