You don’t need a custom validation rule just to confirm that all submitted roles exist in the roles table (unless you want custom logic like the user already having the role). Laravel’s built-in validation can handle this easily if you structure your request so that roles is an array instead of a string.
Recommended Approach
Step 1: In your frontend or API client, send the roles as an array:
{
"roles": ["admin", "editor"]
}
—or, if you must accept a comma-separated string, preprocess it in your FormRequest's prepareForValidation method to convert to an array.
Step 2: In your AssignRoleToUserRequest form request, use the exists rule:
public function rules(): array
{
return [
// 'roles' must be an array
'roles' => ['required', 'array'],
// each element in roles[] must exist in the roles table, 'name' column
'roles.*' => ['required', 'string', 'exists:roles,name'],
];
}
Optional: If the incoming value is a comma-separated string, normalize it first:
protected function prepareForValidation()
{
if (is_string($this->roles)) {
$this->merge([
'roles' => array_map('trim', explode(',', $this->roles))
]);
}
}
Summary
- Validate
rolesas an array, and eachroleexists inroles.name - Use Laravel’s built-in validation rules—no custom rule required
- Normalize string input in
prepareForValidation, if necessary
Example
class AssignRoleToUserRequest extends FormRequest
{
protected function prepareForValidation()
{
if (is_string($this->roles)) {
$this->merge([
'roles' => array_map('trim', explode(',', $this->roles))
]);
}
}
public function rules(): array
{
return [
'roles' => ['required', 'array'],
'roles.*' => ['required', 'string', 'exists:roles,name'],
];
}
public function authorize(): bool
{
return true;
}
}
Conclusion:
You can use Laravel’s built-in array and exists rules to validate that every submitted role exists in the roles table—no custom rule is necessary unless you want to check for more (like whether the user already has a role).