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のルーティング設定では、
###上に書かれた設定が優先的に実行される
ということです。
なので、web.php
に/stadium/create
が一番下に書かれており、
/stadium/{id}
が上にあることで、
-
id
パラメータにcreate
という値を受け渡す - Modelから
id
カラムにcreate
という値が存在しない判定になる -
id
がcreate
である他のカラムも取得できないため、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');