php - Conditional validation on Custom form request

725

on my controller I have:

 public function store(ProductRequest $request)

The request:

class ProductRequest extends Request
{
    public function rules()
    {
        return [
            'name' => 'required|min:3',
            'perTypeTime' => 'sometimes|required',
            'per_type_id' => 'required'
        ];
    }
}

I want to change the perTypeTime rule above to be conditional depending on if per_type_id field == 1.

If I initiated the validator in the controller I believe I could do something like the below:

$v = Validator::make($data, [
    'per_type_id' => 'required|email'
]);

$v->sometimes('perTypeTime', 'required|max:500', function($input)
{
    return $input->per_type_id == 1;
});

Is there a way to do this, while keeping my custom request. I like how this approach keeps the controller cleaner.

I can't seem to access the validator on the request object. Is there a way to specify this condition inside the request itself, or to access the validator from the request object, or is there another way?

825

Answer

Solution:

You can do that

I want to change the perTypeTime rule above to be conditional depending on if per_type_id field == 1.

within yourrules() method in yourProductRequest. For details see required_if:anotherfield,value in the Laravel documentation validation rules.

public function rules()
{
    return [
        'name'          => 'required|min:3',
        'perTypeTime'   => 'required_if:per_type_id,1',
        'per_type_id'   => 'required'
    ];
}
230

Answer

Solution:

Laravel 5.3, in your request file you can add:

use Illuminate\Validation\Factory;

...

public function validator(Factory $factory)
{
    $validator = $factory->make($this->input(), $this->rules());
    $validator->sometimes('your_sometimes_field', 'your_validation_rule', function($input) {
        return $input->your_sometimes_field !== null;
    });
    return $validator;
}
50

Answer

Solution:

Actually this answer https://stackoverflow.com/a/41842050/3922975 is not the best. We don't have to replace default validator with our own (because we are not changing anything). In that solution we hope validation factory will always require only two attributes ($this->input(), $this->rules()) which is actually not true even in time of writing.

This is a default validator used by Laravel:

$factory->make(
    $this->validationData(), 
    $this->container->call([$this, 'rules']),
    $this->messages(), 
    $this->attributes()
);

As you can see it is much different from that Artem Verbo used.

Better solution is to create withValidator method in your ProductRequest class:

use Illuminate\Contracts\Validation\Validator;

...

public function withValidator(Validator $validator)
{
    $validator->sometimes('your_sometimes_field', 'your_validation_rule', function ($input) {
        return $input->your_sometimes_field !== null;
    });
}

People are also looking for solutions to the problem: Capture every instance of a pattern in a string using regex and PHP

Source

Didn't find the answer?

Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.

Ask a Question

Write quick answer

Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.

Similar questions

Find the answer in similar questions on our website.