Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ravasaurio's avatar

required_if validation rule with array values.

I have a form for my admin to create new users. This is where the data is validated:

public function rules()
    {
      return [
            'first_name'     => 'required|max:191',
            'last_name'  => 'required|max:191',
            'email'    => ['required', 'email', 'max:191', Rule::unique('users')],
            'timezone' => 'required|max:191',
            'password' => 'required|min:6|confirmed',
            'roles' => 'required|array',
        ];
    }

In my form, there are some switches you may turn on/off to select the roles you want to assign the new user. roleswill be an array containing the role names you have selected. This is how the array looks like on the logs with more than one role selected:

array ( 

0 => 'administrator',
1 => 'executive',
2 => 'user',
)

What I need is to have some extra fields required, only if the user role was selected:

public function rules()
    {
      return [
            'first_name'     => 'required|max:191',
            'last_name'  => 'required|max:191',
            'email'    => ['required', 'email', 'max:191', Rule::unique('users')],
            'timezone' => 'required|max:191',
            'password' => 'required|min:6|confirmed',
            'roles' => 'required|array',
        'extra_field_1' => 'required_if:',//<--'user' role was selected? then this field will be required
        ];
    }

I have tried something like this:

'extra_field_1' => 'nullable|required_if:roles,User',

'extra_field_1' => 'required_if:roles,==,User',

'extra_field_1' => 'nullable|required_if:roles,user',

'extra_field_1' => 'required_if:roles,==,user',

Testing those, I selected the 'user' role and then left the extra fields empty to see if the validation fails and it doesn`t. Instead I get an SQLexception from trying to insert null data on not null columns (When I send the form, if the users role was selected the value of those extra fields will be inserted on a table which is different from the users table). If I am not mixing concepts, if validation fails the function that stores the user and gets me the SQLexception should not be executed right?

How can I get that required_if working? Thanks.

0 likes
2 replies
ravasaurio's avatar
ravasaurio
OP
Best Answer
Level 2

Hello, I found a way to do it and I will post it here in case someone finds it helpful.

I changed this:

public function rules()
    {
      return [
            'first_name'     => 'required|max:191',
            'last_name'  => 'required|max:191',
            'email'    => ['required', 'email', 'max:191', Rule::unique('users')],
            'timezone' => 'required|max:191',
            'password' => 'required|min:6|confirmed',
            'roles' => 'required|array',
        ];
    }

To this:

public function rules()
    {
      $rules = [
        'first_name'    => 'required|max:191',
        'last_name'     => 'required|max:191',
        'email'         => ['required', 'email', 'max:191', Rule::unique('users')],
        'timezone'      => 'required|max:191',
        'password'    => 'required|min:6|confirmed',
        'roles'         => 'required|array',
      ];

      if(isset(request()->roles))
      {
        if(in_array('commerce',request()->roles))
        {
          $additionalRules = [
            'extra_field_1' =>  'required|alpha',
            'extra_field_2' =>  'required|numeric',
            //etc
          ];
          $rules = $rules+$additionalRules;
        }
      }

      \Log::debug($rules);
      return $rules;
    }

So instead of directly returning the set of rules, I store them on the rulesvariable. Then I check if the rolesarray is present and if it is there, I look for the userstring inside. If userrole was selected, then I create an additional set of rules and combine it with the original one.

This is how ruleslooks like on the logs:

Without userrole selected:

'first_name' => 'required|max:191',
'last_name' => 'required|max:191',
'email' => 
array (
0 => 'required',
1 => 'email',
2 => 'max:191',
3 => 
Illuminate\Validation\Rules\Unique::__set_state(array(
'ignore' => NULL,
'idColumn' => 'id',
'table' => 'users',
'column' => 'NULL',
'wheres' => 
array (
),
'using' => 
array (
),
)),
),
'timezone' => 'required|max:191',
'password'    => 'required|min:6|confirmed',
'roles' => 'required|array',
)

With userrole selected:

'first_name' => 'required|max:191',
'last_name' => 'required|max:191',
'email' => 
array (
0 => 'required',
1 => 'email',
2 => 'max:191',
3 => 
Illuminate\Validation\Rules\Unique::__set_state(array(
'ignore' => NULL,
'idColumn' => 'id',
'table' => 'users',
'column' => 'NULL',
'wheres' => 
array (
),
'using' => 
array (
),
)),
),
'timezone' => 'required|max:191',
'password'    => 'required|min:6|confirmed',
'roles' => 'required|array',
'extra_field_1' =>  'required|alpha',
'extra_field_2' =>  'required|numeric',
)

That way those extra fields are only required when userrole is selected.

Please or to participate in this conversation.