为什么它不应该传递参数 - Laravel 路由

Why is it passing a param when it should not - Laravel Routing

奇怪的问题,让我们看看一些路线:

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 的参数)所以它不应该假设有一个参数。

因为你先定义了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']);

就是说,您可以使用简单的 resource-route.

来进一步简化它
Route::resource('/admin/races', ['as' => 'races.list', 'uses' => 'RacesController'])->only("index", "show", "create", "edit");

已接受答案的另一种解决方案是在参数化路由中为参数指定条件。例如,如果 {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']);

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