Laravel 5.1 当一种方法需要一个字段而另一种方法不需要时,如何对两种方法使用相同的表单请求规则?

Laravel 5.1 How to use the same form request rules for two methods when a field is required in one but not in the other method?

我有一个包含 3 个文件输入字段的表单,用户应该至少上传一个文件。我有一个表单请求,我在其中验证它们如下:

public function rules()
    {
     $this->prepInput();
        return [
            'comment' => 'max:2000',
            'source' => 'different:target',
            'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
            'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
            'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'

        ];
    } 

为了更新相同的表单,我在我的控制器中使用了 update 方法,这与 store 方法几乎相同。唯一的区别是更新表单中不需要文件。有什么方法可以使用 storeupdate 方法使用相同的表单请求并选择性地应用所需的规则?

因为你正在使用一种方法$this->prepInput();我建议你更改一点代码以重用。

  1. 您必须为路由创建和编辑创建命名路由。我假设你正在使用足智多谋的路由
  2. 像下面这样更改您的代码

    public function isEditRequestCalled()
    {
      return app('router')->getCurrentRoute()->getName() == 'YOUR_EDIT_ROUTE_NAME';
    }
    

并在您的请求方法中更改为这样

    public function rules()
    {
      $this->prepInput();
      return $this->isEditRequestCalled() ? [
        //YOUR EDIT RULES GOES HERE
      ] : [//YOUR CREATE RULES GOES HERE
        'comment' => 'max:2000',
        'source' => 'different:target',
        'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
        'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
        'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'

      ];
    }

我使用了以下技巧并且奏效了:

 public function rules()
    {
    $this->prepInput();
        $rules= [
            'comment' => 'max:2000',
            'source' => 'different:target',
            'file1'=>'required_without_all:file2,file3|between:1,15360|mimes:txt,pdf',
            'file2'=>'required_without_all:file1,file3|between:1,15360|mimes:txt,pdf',
            'file3'=>'required_without_all:file1,file2|between:1,15360|mimes:txt,pdf'

        ];
        if($this->myprojects){
            $rules['file1'] = 'between:1,15360|mimes:txt,pdf';
            $rules['file2'] = 'between:1,15360|mimes:txt,pdf';
            $rules['file3'] = 'between:1,15360|mimes:txt,pdf';
        }

          return  $rules;
    }

这里我的路线信息如下:

myprojects/{myprojects}/edit | myprojects.edit | App\Http\Controllers\MyProjectsController@edit

所以我的 myprojects 实体的 ID 是 $this->myprojects。如果它是空的,它正在创建一个 myprojects,如果它有一个值,它正在更新相应的 myprojects.

我使用单独的 Rule 类,它基本上只存储 $rules$messages 我需要在 FormRequest [=19] 中使用和重复使用=].

class RulePrep
{
    /**
     * @var array
     */
    public $rules = [];

    /**
     * @var array
     */
    public $messages = [];
}

class RuleProjects
{
    /**
     * @var array
     */
    public $rules = [];

    /**
     * @var array
     */
    public $messages = [];
}

你可以试试吗? 您需要单独的 FormRequest 类,但它可能比所有捆绑在一起的条件逻辑更整洁。

我基本上是为我的两个请求使用抽象基础 class,然后在子classes 中添加任何需要的规则。这将保留 DRY 并提供一种灵活的方式来添加规则。例如:

abstract class CompanyBaseRequest extends FormRequest
{
    ...
    public function rules()
    {
        return [
            'name' => ['required', 'string', 'max:255'],
            'category_id' => ['required', 'exists:company_categories,id'],
            'short_description' => ['required', 'string', 'max:2000'],
            'video' => ['nullable', 'file', 'mimes:mp4', 'max:30000'],
        ];
    }
}

然后是两个子classes:

class CompanyStoreRequest extends CompanyBaseRequest
{
    ...
    public function rules()
    {
        return array_merge(parent::rules(), [
            'logo' => ['required', 'file', 'mimes:png,jpg,jpeg', 'max:1024'],
        ]);
    }
}
class CompanyUpdateRequest extends CompanyBaseRequest
{
    ...
    public function rules()
    {
        return array_merge(parent::rules(), [
            'logo' => ['nullable', 'file', 'mimes:png,jpg,jpeg', 'max:1024'],
        ]);
    }
}

您应该在需要时使用这些子class之一,它们都将包含来自基础 class 的规则和来自它们自身的规则。

这比接受的答案更好,因为表格本身明确说明了他们以自己的名义所做的事情,而不是只在一个条件下工作(不清楚他们检查的是什么)。