为什么在不应该传递参数的情况下-Laravel路由

时间:2020-10-15 20:34:46

标签: laravel routes laravel-routing

Bizarre问题,让我们看看一些路线:

Route::get('/admin/races', ['as' => 'races.list', 'uses' => 'RacesController@index']);
Route::get('/admin/races/{race}', ['as' => 'races.race', 'uses' => 'RacesController@show']);
Route::get('/admin/races/create', ['as' => 'races.create', 'uses' => 'RacesController@create']);
Route::get('/admin/races/{race}/edit', ['as' => 'races.edit', 'uses' => 'RacesController@edit']);

看起来很正常,让我们看一下控制器:

class RacesController extends Controller {

    public function index() {
        return view('admin.races.list');
    }

    public function show(GameRace $race) {
        return view('admin.races.race', [
            'race' => $race,
        ]);
    }

    public function create() {
        return view('admin.races.manage', [
            'race' => null,
        ]);
    }

    public function edit(GameRace $race) {
        return view('admin.races.manage', [
            'race' => $race,
        ]);
    }
}

看起来很正常。问题是:

我去/admin/races/create时得到404。原因是因为,例外:

Illuminate\Database\Eloquent\ModelNotFoundException^ {#851
  #model: "App\Flare\Models\GameRace"
  #ids: array:1 [
    0 => "create"
  ]
  #message: "No query results for model [App\Flare\Models\GameRace] new"
  #code: 0
  #file: "./vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php"
  #line: 47
  trace: {
   .....

为什么要打电话:

<li><a href="{{route('races.create')}}">Create Race</a></li>

使Laravel接受create一词并将其作为模型注入?我没有其他路线,就是这样做。对于上下文,这是我们创建项目的方式:

Route::get('/admin/items/create', ['as' => 'items.create', 'uses' => 'ItemsController@create']);

相同的概念,而不是竞赛其项目。那么laravel怎么搞砸了?

我已经运行了所有缓存清除和路由清除以及所有内容。同样的问题。甚至测试都失败了。不,我在哪里用参数来称呼它(尤其是没有一个叫做create的参数),因此它不应该假设存在一个参数。

2 个答案:

答案 0 :(得分:1)

这是因为您首先定义了Route::get('/admin/races/{race}' ..,所以无论值是多少,它都会到达该路径。只需将create路线移到show路线即可解决您的问题。

Route::get('/admin/races', ['as' => 'races.list', 'uses' => 'RacesController@index']);
Route::get('/admin/races/create', ['as' => 'races.create', 'uses' => 'RacesController@create']);
Route::get('/admin/races/{race}', ['as' => 'races.race', 'uses' => 'RacesController@show']);
Route::get('/admin/races/{race}/edit', ['as' => 'races.edit', 'uses' => 'RacesController@edit']);

也就是说,您可以通过简单的资源路由进一步简化此操作。

Route::resource('/admin/races', ['as' => 'races.list', 'uses' => 'RacesController'])->only("index", "show", "create", "edit");

答案 1 :(得分:0)

对已接受答案的另一种解决方案是为参数化路径中的参数指定条件。例如,如果{race}需要为数字,则可以执行以下操作:

Route::get('/admin/races', ['as' => 'races.list', 'uses' => 'RacesController@index']);
Route::get('/admin/races/{race}', ['as' => 'races.race', 'uses' => 'RacesController@show'])->where('race', '\d+');
Route::get('/admin/races/create', ['as' => 'races.create', 'uses' => 'RacesController@create']);
Route::get('/admin/races/{race}/edit', ['as' => 'races.edit', 'uses' => 'RacesController@edit']);

这在您无法控制路由顺序的情况下很有用(例如,有一个程序包注册了冲突的路由)。