Laravel form request: how to avoid n+1 queries when validating arrays?

Viewed 66

I wanted to know the best approach when validating arrays of a lot elements.

For example,

    <?php
   
    namespace App\Http\Requests;

    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Http\Request;
    
    class UsersRolesAssignmentRequest extends FormRequest
    {
        public function rules(Request $request)
        {
            return [
                'roles' => 'array|min:1',
                'roles.*.role_id' => 'required|exists:roles',
                'roles.*.user_id' => 'required|exists:users'
            ];
        }
    }

The problem here is if i have 100 elements i will need to touch the database 200 times.

1 Answers

I'm not sure it's checking against the DB 200 times, that seems like a pretty large oversight. But, if it is, you can use the in() rule, along with some pre-fetched results instead:

public function rules(Request $request){
  $roleIds = Role::pluck('id')->implode(',');
  $userIds = User::pluck('id')->implode(',');
  return [
    'roles' => 'array|min:1',
    'roles.*.role_id' => "required|in:{$roleIds}",
    'roles.*.user_id' => "required|in:{$userIds}"
  ];
}

Just don't forget to import your Models via use App\Models\User; and use App\Models\Role (or whatever path your Models are at).

This rule will generate the following:

'roles.*.role_id' => 'required|in:1,2,3,4,5', // ... 
'roles.*.user_id' => 'required|in:1,2,3,4,5
Related