Laravel 5.8 Validation - always bail on any rule
Asked Answered
G

3

7

Is there any possibility to set FormRequest rules to default use bail rule without typing in it?

Instead of:

class StoreRequest extends FormRequest {
    function rules() {
        return [
            'name' => 'bail|required|min:3',
            'last_name' => 'bail|required|min:3',
            'names' => 'bail|required|min:3',
            'email' => 'bail|required|email',
            'type' => 'integer|min:10|max:50',
            // [...]
        ];
    }
}

I would like to get more cleaner version, like:

class StoreRequest extends FormRequest {

    protected $stopsOnFirstError = true; // I can't find anything like this

    function rules() {
        return [
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email',
            'type' => 'integer|min:10|max:50',
            // [...]
        ];
    }
}

Update:

Some of my rules are defined as array:

'type' => [
    'bail',
    'required',
    'integer',
    Rule::in(ContactType::getValues()),
],
Guayaquil answered 18/3, 2019 at 7:15 Comment(3)
I believe that would require overriding the existing validator functions.Methodism
bail is already implicit with the required rule so it is not necessary. However bail will not work in preventing other fields from validating it only stops the other validation rules on the one field it's validating.Pinfold
This is what I trying to achieve - stop other validations when first fails. I also have not required fields but validated when present: `bail|integer|min:10'.Guayaquil
S
2

1) Without making it more complex use string replacement

<?php
$rules = [
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email'
        ];
$stopsOnFirstError = true;
if(stopsOnFirstError){
  array_walk($rules, function(&$value, $key) { $value = 'bail|'.$value; } );
}

print_r($rules);
?>

Live Demo : Link

Output :

Array
(
    [name] => bail|required|min:3
    [last_name] => bail|required|min:3
    [names] => bail|required|min:3
    [email] => bail|required|email
)

2) You can also do this in other way , by just adding '*' => 'bail', to apply for all fields

class StoreRequest extends FormRequest {
    function rules() {
        return [
            '*' => 'bail',
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email',
        ];
    }
}
Sedan answered 18/3, 2019 at 7:30 Comment(5)
Very interesting approachMethodism
Nice idea, but I've some rules defined as array with closures or Rule::in method. I'm updated my question.Guayaquil
@Daniel: so will not work with '*' => 'bail', ? did you try this ?Sedan
@NikleshRaut: I just checked, unfortunately it not works.Guayaquil
Pretty simple approach. The idea seems interesting. Would be nice if Laravel came with an option like that by defaultSacerdotal
P
1

You can always override the validator method in your form request class:

class StoreRequest extends FormRequest {

    private function prependBailOnRule($rule) {
        if (is_string($rule)) {
            return "bail|".$rule;
        } else if (is_array($rule)) {
           return array_merge([ "bail" ], $rule);
        }
    }

    //Adapted from FromRequest::createDefaultValidator
    public function validator(ValidationFactory $factory) {
        return $factory->make(
             $this->validationData(), 
             array_map([$this, 'prependBailOnRule' ], $this->container->call([$this, 'rules'])),
             $this->messages(), $this->attributes()
        );
    }

    function rules() {
        return [
            'name' => 'required|min:3',
            'last_name' => 'required|min:3',
            'names' => 'required|min:3',
            'email' => 'required|email',
            'type' => 'integer|min:10|max:50',
            // [...]
        ];
    }
}
Pinfold answered 18/3, 2019 at 9:41 Comment(0)
P
1

Here I'm using Laravel 8 and easily stop the validating on the first error by setting the $stopOnFirstFailure = true;

class StoreRequest extends FormRequest{
protected $stopOnFirstFailure = true;

public function rules()
{
    return [
        'name'      => 'required|min:3',
        'last_name' => 'required|min:3',
        'names'     => 'required|min:3',
        'email'     => 'required|email',
    ];
}

}

Piapiacenza answered 24/5, 2021 at 8:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.