【问题标题】:Laravel 5.5 cannot make validator in a form Request classLaravel 5.5 无法在表单请求类中制作验证器
【发布时间】:2018-07-13 18:59:33
【问题描述】:

我想检查是否仅当两个“villes”具有相同名称时才填写表单输入“departement”。

在控制器内,这段代码完美地工作:

 $rules=[  'nom' => 'required', 'ville'=> 'required|exists:villes,nom'];
 $messages = [
      'depart.required' => 'Deux villes portent le même nom, preciser le 
 département'];
  $validator = Validator::make($request->All(), $rules,$messages);
  $validator->sometimes('depart_id', 'required|exists:departs,id', function 
  ($input) {
      return Ville::where('nom',$input->ville)->count()>1;
  });
  if ($validator->fails()) {
    return redirect('admin/etab/create')
            ->withErrors($validator)
            ->withInput();
    }

我将相同的代码放在表单请求类中:

public function rules()
{
  $rules=[  'nom' => 'required', 'ville'=> 'required|exists:villes,nom'];
  $messages = [
      'depart.required' => 'Deux villes portent le même nom, preciser le 
  département',
  ];
  $validator = Validator::make($this->All(), $rules,$messages);
  $validator->sometimes('depart_id', 'required|exists:departs,id', function 
  ($input) {
      return Ville::where('nom',$input->ville)->count()>1;
  });
  return $validator;
}

我收到"Type error: Argument 2 passed to Illuminate\Validation\Factory::make() must be of the type array, object given," 我认为错误消息不充分,但我找不到为什么这种方式不起作用

谢谢......

【问题讨论】:

  • 不要覆盖框架类,只是,不要。查看laravel.com/docs/5.5/validation#form-request-validation
  • FormRequest 类中的 rules 方法应该返回一个数组,而不是一个 Validator 对象。这就是您在此处看到的错误。
  • @Robert 我知道规则不是我的代码的好地方,但我找不到 int 文档应该在 FormRequest 中的哪个位置放置我的代码...
  • @aprokryfos 抱歉,我没有重写框架请求类,我创建了一个 FormRequest 类。 (我编辑了帖子)

标签: laravel laravel-5 custom-validators


【解决方案1】:

您可以查看vendor/laravel/framework/src/Illuminate/Foundation/Http/FormRequest.php 中的FormRequest 类并查看它的作用。

它在顶部包含这两个方法:

/**
 * Get the validator instance for the request.
 *
 * @return \Illuminate\Contracts\Validation\Validator
 */
protected function getValidatorInstance()
{
    $factory = $this->container->make(ValidationFactory::class);

    if (method_exists($this, 'validator')) {
        $validator = $this->container->call([$this, 'validator'], compact('factory'));
    } else {
        $validator = $this->createDefaultValidator($factory);
    }

    if (method_exists($this, 'withValidator')) {
        $this->withValidator($validator);
    }

    return $validator;
}

/**
 * Create the default validator instance.
 *
 * @param  \Illuminate\Contracts\Validation\Factory  $factory
 * @return \Illuminate\Contracts\Validation\Validator
 */
protected function createDefaultValidator(ValidationFactory $factory)
{
    return $factory->make(
        $this->validationData(), $this->container->call([$this, 'rules']),
        $this->messages(), $this->attributes()
    );
}

所以你基本上可以在你自己的 FormRequest 类中提供一个validator 方法来创建一个自定义的 Validator 对象,该方法将 ValidatorFactory 作为参数。

在您的情况下,您不需要这样做,因为您只想将 sometimes 规则附加到默认验证器。看上面的代码,它检查withValidator方法是否存在,如果存在则调用:

    if (method_exists($this, 'withValidator')) {
        $this->withValidator($validator);
    }

您可以创建 FormRequest,确保正确使用 rulesmessagesauthorize 方法,例如规则和消息返回数组,授权返回布尔值。

然后创建一个withValidator 方法,在该方法中将有时规则附加到验证器。

/**
 * Do foo with Validator
 *
 * @param \Illuminate\Contracts\Validation\Validator $validator
 * @return void
 */
public function withValidator(Validator $validator)
{
    $validator->sometimes('depart_id', 'required|exists:departs,id', function {
        return Ville::where('nom', $this->input('ville'))->count() > 1;
    });
}

这样sometimes 在执行验证之前会附加到您的验证器。

【讨论】:

    【解决方案2】:

    您不会将所有验证逻辑都放在这样的规则方法中。只有规则定义在那里。你只需要这个:

    public function rules()
    {
      return [
        'nom' => 'required', 
        'ville'=> 'required|exists:villes,nom',
      ];
    }
    

    Laravel 将从那里开始处理验证。使用FormRequests时无需手动创建Validator类。

    自定义消息涉及在类中创建messages 方法,如下所示:

    public function messages()
    {
        return [
            'depart.required' => 'Deux villes portent le même nom, preciser le départemen'
        ];
    }
    

    更新

    至于sometimes 规则,我建议创建一个Rule 对象并自定义您需要如何检查2 个同名的别墅。

    Rule classes

    【讨论】:

    • 检查 ville 是否存在就可以了。但我想检查部门是否仅存在于两个别墅具有相同名称的情况下。为此,我需要一个 sometmes 规则....
    • 好的,但我发布的是 FormRequest 类需要如何布局。在rules 方法中拥有验证器实例和消息数组的方式是错误的。需要删除这些才能使 FormRequest 类正常工作
    猜你喜欢
    • 2018-09-15
    • 2018-06-16
    • 2018-06-30
    • 2018-09-13
    • 2018-06-26
    • 2016-09-06
    • 2018-05-09
    • 2016-09-02
    相关资源
    最近更新 更多