Search code examples
phplaraveleloquentlaravel-validation

Using models relationships in Laravel Validation Rule 'Exists'


Db schema

users
 -id
 -name
 -email
 ...

roles
 -id
 -name

User may have multiple roles and vice-versa (i already defined relationships in models)

pivot table

role_user
 -id
 -user_id
 -role_id

Validation rule trying to make: user_id must exist in users table and has role id = 4

//...
'user_id' => ['nullable', Rule::exists('users')->where(
                function ($query) { 
                    $query->whereHas('roles', 
                        function ($q) { 
                            $q->where('id', 4); 
                        }
                    );
                }
)], 
//...

Error message : "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'has' in 'where clause' (SQL: select count(*) as aggregate from users where user_id = 0 and (has = roles))"


Solution

  • I would use this. This will solve your problem, but i don't know either is the best way or not.

        use Validator; // on the top
    
        $validator = Validator::make($request->all(), [
            'user_id' => 'nullable|numeric|exists:users,id',
        ]);
        if ($validator->fails()) {            
            return response()->json($validator->errors(), 422);
        }
        $user = User::find($request->user_id);
        if(!$user || !$user->roles->first() || $user->roles->first()->id != 4) {
            return response()->json(['user_id'=>['You dont have permission.']], 422);
        }
    

    Another way you can try

    'user_id'  => [
                'nullable',
                'numeric',
                'exists:users,id',
                function ($attribute, $value, $fail) { 
                    $editorsIDs = User::whereHas('roles', function ($q) {
                        $q->where('id', 4);
                    })->pluck('id');
    
                    if(! $editorsIDs->contains($value)) {                        
                        $fail('You dont have permission.');
                    }}
                ]