Trent
Trent

Reputation: 3103

Laravel 5.4 sometimes|required validation not raising on "null" input

I'm having a problem validating inputs that are only going to be present sometimes in the Request.

// Controller
public function update(Request $request, User $user)
{    
    $updateResult = $user->updateUser($request);
    return dd($updateResult);
}

// User Model

protected $validation = [
    'rules' => [
        'email' => [
            'sometimes',
            'email',
            'required',
        ],
        'password' => [
            'sometimes',
            'min:6',
            'required',
        ],
        'first_name' => [
            'sometimes',
            'required',
        ],
        'last_name' => [
            'sometimes',
            'required',
        ],
    ],
    'messages' => [
        'email.required' => 'An email is required.',
        'email.email' => 'The email must be valid.',
        'password.required' => 'A password is required.',
        'password.min' => 'Your password must be at least six (6) characters long.',
        'first_name.required' => 'Your first name is required.',
        'last_name.required' => 'Your last name is required.',
    ],
];

public function updateUser(Request $request)
{
    $validation = Validator::make($request->all(), [
        $this->validation['rules'],
        $this->validation['messages'],
    ]);

    if ($validation->fails())
    {
        return $validation;
    }

    else
    {
        return "OK";
    }
}

So in some update pages $request->all() is only going to have a subset of these fields. However, even a field is present, but the value is null, the required doesn't trigger.

[
    'first_name' => null,
    'last_name' => 'Davidson',
    'job_title' => 'Tech Support',
]

The above request array will return "OK"... If I remove sometimes from the fields, then when a partial input request is sent, it fails saying the fields are required.

I am clearing missing something here, but from reading the docs I thought I'd configured this correctly:

In some situations, you may wish to run validation checks against a field only if that field is present in the input array. To quickly accomplish this, add the sometimes rule to your rule list:

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

Upvotes: 1

Views: 6306

Answers (3)

shock_gone_wild
shock_gone_wild

Reputation: 6740

The problem you are facing is simply due to an error in your call to the validator. The second parameter is not a multidimensional array as you passed. The rules array and the messages array are separate parameters.

$validation = Validator::make($request->all(), [
    $this->validation['rules'],
    $this->validation['messages'],
]);

Should be replaced by

    $validation = Validator::make($request->all(),
        $this->validation['rules'], $this->validation['messages']);

Upvotes: 3

Dimitri Mostrey
Dimitri Mostrey

Reputation: 2355

'first_name' => [
        'sometimes',
        'required',
    ],

Will never work as expected. Sometimes indicates: if something comes, what is the next rule? In this case 'required'. Required what? Change this to:

'first_name' => [
        'sometimes',
        'required',
        'min:1',
    ],

The null value will still be a null value if no input is given and won't fail. If you want to keep the value of the field in the table for updates, populate the input in the form with it's respected values.

The null value was send as '' and got nulled by the ConvertEmptyStringsToNull::class in the app\Http\kernel.php middleware.

Upvotes: 0

Serge
Serge

Reputation: 2187

In Laravel 5.4 empty strings are converted to Null by the ConvertEmptyStringsToNull middleware... that might cause you some issues...

You should add nullable to all your optional validations...

Hope this helps

Upvotes: 1

Related Questions