Laravel 5.5 无法在表单请求中创建验证器 class

Laravel 5.5 cannot make validator in a form Request class

我想检查是否仅当两个 '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();
    }

我将相同的代码放入表单请求中 class:

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," 我认为错误消息不充分,但我找不到为什么这种方法不起作用

谢谢......

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

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

Laravel 将从那里开始处理验证。使用 FormRequests.

时不需要手动创建 Validator class

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

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

更新

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

Rule classes

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

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

/**
 * 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 class 中提供一个 validator 方法来创建自定义 Validator 对象,该方法将获取 ValidatorFactory 作为参数。

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

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

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

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

/**
 * 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 在执行验证之前附加到您的验证器。