2

I am developing a Web application using Laravel. What I am doing now is creating a FirmRequest for the validation.

This is my FormRequest.

use Illuminate\Foundation\Http\FormRequest;

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

    public function rules()
    {
        return [
            'title' => 'required',
            'type' => 'required',
            'complex_field' => ...need complex conditional validation based on the type field
        ];
    }
}

If I did not use the FormRequest, I can create validator in the controller and set complex conditional validation rule like this.

$v = Validator::make($data, [
    //fields and rules
]);

$v->sometimes('reason', 'required|max:500', function ($input) {
    return $input->games >= 100;
});

But the issue is that I am not creating the Validator in the controller. But I am using the FormRequest. How can I achieve the same thing in the FormRequest?

Wai Yan Hein
  • 13,651
  • 35
  • 180
  • 372

3 Answers3

8

You can manually adjust the rules depending on the input data:

class StoreVacancy extends FormRequest
{
    public function rules()
    {
        $reason = $this->request->get('reason'); // Get the input value
        $rules = [
            'title' => 'required',
            'type'  => 'required',
        ];

        // Check condition to apply proper rules
        if ($reason >= 100) {
            $rules['complex_field'] = 'required|max:500';
        }

        return $rules;
    }
}

Its not the same as sometimes, but it does the same job.

thefallen
  • 9,496
  • 2
  • 34
  • 49
3

Since 5.4 you can use the method "withValidator" inside your FormRequest: https://laravel.com/docs/5.4/validation

This method receives the fully constructed validator, allowing you to call any of its methods before the validation rules are actually evaluated

use Illuminate\Foundation\Http\FormRequest;

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

    public function rules()
    {
        return [
            'title' => 'required',
            'type' => 'required',
        ];
    }

    public function withValidator($validator)
    {
        $validator->sometimes('reason', 'required|max:500', function ($input) {
            return $input->games >= 100;
        });
    }
}
atthakasem
  • 31
  • 1
  • This is a great answer as gives a lot of flexibility by allowing the user full access to the input object so can check against any params and also add built in validation or custom ones. – omarjebari Oct 20 '21 at 12:44
1

You can check the createDefaultValidator function in https://github.com/laravel/framework/blob/5.7/src/Illuminate/Foundation/Http/FormRequest.php. We will override that function and add our condition

    /**
     * Add Complex Conditional Validation to the validator instance.
     *
     * @param  \Illuminate\Validation\Factory  $factory
     * @return \Illuminate\Validation\Validator
     */
    public function validator($factory)
    {
        $validator = $factory->make(
            $this->validationData(),
            $this->container->call([$this, 'rules']),
            $this->messages(),
            $this->attributes()
        );

        $validator->sometimes('reason', 'required|max:500', function ($input) {
            return $input->games >= 100;
        });

        return $validator;
    }
Quinn Wynn
  • 1,334
  • 2
  • 15
  • 20