Implicit Route Model Binding

南笙酒味 提交于 2019-12-24 08:07:42

问题


Laravel's implicit route model binding isn't working. It is not looking up the record indicated by the identifier. I'm getting a brand new model object.

Given this code:

Route::get('users/{user}', function (App\User $user, $id) {
    $user2 = $user->find($id);
    return [
        [get_class($user), $user->exists, $user],
        [get_class($user2), $user2->exists],
    ];
});

And this URL: /users/1

I get this output:

[["App\\User",false,[]],["App\\User",true]]

I'm on PHP 7.2 and Laravel 5.6.


Additional Information

I've successfully accomplished implicit route model binding in other Laravel projects. I'm working on an existing codebase. As far as I can tell, the feature hasn't been used previously.

The user record exists. It has not been soft deleted. The model does not use the SoftDeletes trait.

I've tried this using various unique route names and other models.

I've checked the App\Http\Kernel class for the usual culprits. $middlewareGroups has \Illuminate\Routing\Middleware\SubstituteBindings::class, in the web section and $routeMiddleware contains 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,.


回答1:


It should work without any problem in Laravel. I've just verified it in my Laravel 5.6 app and there is no problem with this.

Possible scenarios why are you getting this:

  • user is soft deleted
  • this route is not inside web.php or api.php file - the both groups have set bindings (or \Illuminate\Routing\Middleware\SubstituteBindings::class) inside $midddlewareGroups property in app/Http/Kernel.php file
  • you removed mentioned bindings from one of those groups
  • you have set some custom binding. For example if you defined somewhere code like this: Route::bind('user', function($user) { return new \App\User(); });

    then you would get result as you showed because you use custom logic and just return empty user model.

If you think all above are false, I would start with fresh Laravel 5.6 application to try to replicate the issue.




回答2:


I finally resolved this issue. The routes in routes/web.php did not have the web middleware. This is normally done in app/Providers/RouteServiceProvider.php in the mapWebRoutes() function. At some point, during a Laravel upgrade, the route definition got mangled. It looked like this:

        Route::group([
            'namespace' => $this->namespace,
        ], function ($router) {
            require base_path('routes/web.php');
        });

It could have been updated, using that older definition style, to look like this:

        Route::group([
            'middleware' => 'web',
            'namespace' => $this->namespace,
        ], function ($router) {
            require base_path('routes/web.php');
        });

Instead, I just copied the latest method chaining style from the laravel/laravel project, so it now looks like this:

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
             ->namespace($this->namespace)
             ->group(base_path('routes/web.php'));
    }


来源:https://stackoverflow.com/questions/51660203/implicit-route-model-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!