将操作设为资源详细信息页面的可选

时间:2019-01-18 09:53:05

标签: laravel laravel-nova

比方说,我对Product资源有操作“禁令”,而Product模型具有is_banned字段。无需在Product已被禁止(is_banned=1)的详细信息页面上显示“禁止”操作。

Laravel Nova文档提供了根据管理员是否有权执行隐藏操作的示例:

public function actions(Request $request)
{
    return [
        (new Actions\EmailAccountProfile)->canSee(function ($request) {
            return $request->user()->can(
                'emailAnyAccountProfile', User::class
            );
        }),
    ];
}

但是,它没有涵盖当在单个资源的上下文中(在其详细信息页面上)调用此方法时,如何在canSee解析中提供的闭包中获取当前资源的模型实例。

actions()是我们注册可用操作的方法,在我的情况下,它属于Product Nova资源类,但它也无法访问Eloquent模型的上下文。

如何实现?

1 个答案:

答案 0 :(得分:1)

进行一些调试后,我发现资源的actions()方法收到具有Laravel\Nova\Http\Requests\NovaRequest方法的findModelOrFail()实例,并且对于单个资源(例如,在查看资源的详细信息页面时)的请求获取resourceId参数。

因此,基于请求中resourceId的存在,我现在可以确定我是否在单个资源操作的上下文中。然后,我将使用此ID提取资源的模型,并检查其is_banned属性以解决资源的可用操作。

我的动作解析逻辑最终变为:

public function actions(Request $request)
{
    if ($request->resourceId !== null) {
        $product = $request->findModelOrFail($request->resourceId);

        if ($product->is_banned) {
            return [];
        }
    }

    return [new Actions\BanProduct];
}

请注意,findModelOrFail()方法可以在没有$resourceId参数的情况下被调用,并且在这种情况下将自动从请求中获取resourceId的值,但是直接指定代码的意图更加清晰。