首页 > 解决方案 > Laravel - 表单请求中的模型关系验证

问题描述

Form Request我需要根据模型关系中的数据对我的数据进行一些验证。我想出了一个解决方案,但我不知道这是否是最好的方法。有人可以告诉我是否有更好的方法吗?

我当前的控制器方法:

public function headerMapping(HeaderMappingRequest $request, $workspace, $bulk)
{
    $workspace = auth()->user()
        ->activeWorkspaces()
        ->where('uuid', $workspace)
        ->firstOrFail();

    $bulk = $workspace->messageTemplateBulks()
        ->with(['number', 'template', 'user'])
        ->where('uuid', $bulk)
        ->firstOrFail();

    // Do some logic
    $workspace->doSomeLogic();
    $bulk->doSomeLogic();

    return MessageTemplateBulkResource::make($bulk);
}

我无法使用Implicit Route Model Binding,因为我需要获取与用户相关的路由参数模型。

我当前的表格请求:

class HeaderMappingRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {

        // Needs to add custom validation
        // 'header' => [Rule::requiredIf($bulk->template->featureHeaderIsEnabled())]
        // 'buttons' => [Rule::requiredIf($bulk->template->featureButtonsIsEnabled())]

        return [
            'number' => 'required',
            'header_file' => 'required_if:header_from_file,true|file'
        ];
    }
}

我需要根据批量模板关系进行自定义验证,因此我考虑将这些模板传递给Form Request.

我做了以下工作,但我不知道这是否是解决此问题的更好方法:

控制器方法重构:

public function headerMapping(HeaderMappingRequest $request, $workspace, $bulk)
{
    // Do some logic
    $request->workspace->doSomeLogic();
    $request->bulk->doSomeLogic();

    return MessageTemplateBulkResource::make($request->bulk);
}

表单请求重构:

class HeaderMappingRequest extends FormRequest
{
    public function authorize()
    {
        $this->workspace = auth()->user()
            ->activeWorkspaces()
            ->where('uuid', $this->route('workspace'))
            ->firstOrFail();

        $this->bulk = $this->workspace->messageTemplateBulks()
            ->with(['number', 'template', 'user'])
            ->where('uuid', $this->route('bulk'))
            ->firstOrFail();

        return true;
    }

    public function rules()
    {
        return [
            'number' => 'required',
            'header' => [Rule::requiredIf($this->bulk->template->featureHeaderIsEnabled())],
            'buttons' => [Rule::requiredIf($this->bulk->template->featureButtonsIsEnabled())],
            'header_file' => 'required_if:header_from_file,true|file'
        ];
    }
}

对此有什么想法吗?

标签: laravel

解决方案


你的代码还不错,但我会改变一些东西,使用这些技巧中的任何一个,但只使用其中一个:

  1. 您可以使用隐式绑定,但您必须使用 Laravel 8 才能将其用作关系检查。
    • 在您的情况下,这将类似于:Route::get('/header/{activeWorkspaces:uuid}/{messageTemplateBulks:uuid}', ...);. 也许,因为您没有User像文档所说的那样在 URL 中指定,所以您必须检查 是否activeWorkspaces与 current 相关联user,因此messageTemplateBulks:uuid肯定会activeWorkspaces像文档所说的那样相关,但您必须对其进行测试。
    • 此外,当您authorize在您的 中时FormRequest,请检查activeWorkspaces是否与 相关,仅此user而已。
  2. 另一种方法是执行您在方法中所做的事情authorize,而不是firstOrFail针对每个查询,运行first()和返回(bool) $this->workspace && (bool) $this->bulk,因此如果它们中的任何一个是null,它不会授权,因为它们不相关。

推荐阅读