0

我正在尝试使用 Laravel 的路由模型绑定。我在 RoutesServiceProvider 中设置了一个绑定来执行一些自定义解析逻辑。这适用于attributable需要字符串名称和 id 来解析的参数。

但是,当我尝试键入强制转换方法以利用另一个模型的隐式绑定时,它会失败并出现错误

传递给 Illuminate\Routing\Router::{closure}() 的参数 2 必须是 App\Models\Staff 的实例,给定字符串,在 /var/www/html/ngj_form/vendor/laravel/framework/src/Illuminate 中调用/Routing/Route.php 在第 198 行

经过一些调试,我可以看到它{attrId}在下面的方法定义中将路由的一部分作为第二个类型转换参数传递。ID 是一个字符串,因此它失败了。但是为什么它甚至试图传递这个参数呢?

路线如下所示:

Route::get('/admin/create-staff-payment/{attributable}/{attrId}/staff-member/{staff}/', 'Admin\StaffBalances@granularStaffBalance');

类型转换控制器方法如下所示:

 public function granularStaffBalance(Attributable $attributable, Staff $staff)
{
    dd('huh?');
}

RouteServiceProvider 看起来像这样:

  public function boot()
{

    // Bind Attributable (wedding|trial)
    Route::bind('attributable', function ($attributable, $route) {

        $attributableId = $route->parameter('attrId');

        switch($attributable){
            case 'wedding':
                $attributable = Wedding::class;
                break;
            case 'trial':
                $attributable = Trial::class;
                break;
            default:
                throw new \Exception('Type parameter provided is not supported.'); //TODO change this to 404 redirect
        }

        return $attributable::where('id', $attributableId)->firstOrFail();
    });

...
4

1 回答 1

0

好的,经过进一步研究(不感谢 Laravel 文档),我认为这是预期的行为。如果您在路由中传递三个参数,您的控制器方法将期望按照它们在 url 中出现的顺序接收它们。我想我从文档中假设参数的选择比这更智能,但我猜错了。

我解决它的方法是通过另一个帖子中的答案。

显然,您可以忘记参数作为丢弃它们的一种方式,这让我的控制器方法接受两个参数而不是三个参数。

所以现在我RouteServiceProvider看起来像这样(在这里发布以防它帮助其他人):

 public function boot()
    {

        parent::boot();

        // Bind Attributable (wedding|trial)
        Route::bind('attributable', function ($attributable, $route) {

            $attributableId = $route->parameter('attrId');

            switch($attributable){
                case 'wedding':
                    $attributable = Wedding::class;
                    break;
                case 'trial':
                    $attributable = Trial::class;
                    break;
                default:
                    throw new \Exception('Type parameter provided is not supported.'); //TODO change this to 404 redirect
            }

            // We don't want to use this parameter in any controller methods so we can drop it here.
            // This fixes an issue where it was being passed into methods that needs $attributable, $staff
            $route->forgetParameter('attrId');

            return $attributable::where('id', $attributableId)->firstOrFail();
        });
...
于 2021-02-22T19:12:56.583 回答