How do I report every field's validation errors in Laravel?


I'm in the process of moving validation into model (watson/validating package). But some validation rules can't be moved. For instance, consider user registration form. You want to enforce passwords to be no less then 6 characters. You can't do it in the model, since in the model you've got hash of the password.

But then, if your password fails to pass controller validation rules, only errors from controller validation are reported. I'd obviously like user to see results of both controller and model validation.

Show source
| laravel   | validation   | php   2017-01-07 21:01 1 Answers

Answers ( 1 )

  1. 2017-01-07 22:01

    Here's what I came up with:

    class RegisterController extends Controller
        protected function validator(array $data)
            $rules = merge_validation_rules((new User)->getRules(), [
                'email' => 'required',
                'password' => 'min:6',
            return Validator::make($data, $rules);

    merge_validation_rules helper:

    function merge_validation_rules($a, $b)
        $r = $a;
        foreach ($b as $k => $v)
            if (isset($a[$k])) {
                $r[$k] = array_merge(explode('|', $a[$k]), explode('|', $b[$k]));
                if (in_array('sometimes', $r[$k])
                && in_array('required', $r[$k]))
                    $r[$k] = array_diff($r[$k], ['sometimes']);
                $r[$k] = implode('|', $r[$k]);
            } else
                $r[$k] = $b[$k];
        return $r;

    merge_validation_rules test:

    namespace Tests;
    use Tests\TestCase;
    class HelpersTest extends TestCase
         * @dataProvider mergeValidationRulesProvider
        function testMergeValidationRules($input, $output)
            $r = call_user_func_array('merge_validation_rules', $input);
            $this->assertEquals($output, $r);
        function mergeValidationRulesProvider() { return [
            [[['a' => 'ra1', 'b' => 'rb1'], ['a' => 'ra2', 'c' => 'rc1']],
                ['a' => 'ra1|ra2', 'b' => 'rb1', 'c' => 'rc1']],
            [[['a' => 'sometimes'], ['a' => 'required']],
                ['a' => 'required']],
        ]; }

    Here you can see one more issue. I'm using both user/password and social logins. So email is not always present (not every social networks returns it). So in the model I have 'email' => 'sometimes|email', but in registration controller I want it to be required. For now I remove sometimes if required is present. We'll see if it'll work out.

◀ Go back