【问题标题】:Why is it passing a param when it should not - Laravel Routing为什么它不应该传递参数 - Laravel Routing
【发布时间】:2021-01-30 09:24:50
【问题描述】:

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

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

【问题讨论】:

    标签: laravel routes laravel-routing


    【解决方案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");
    

    【讨论】:

    • 6 分钟后我可以接受!至于你的最后一点,我从来不知道。谢谢好人!
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2019-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-16
      • 1970-01-01
      • 2013-07-26
      • 2023-03-13
      • 2012-06-23
      相关资源
      最近更新 更多