Rule::exists() doesn't give you an Eloquent builder.
Instead, it uses the query builder directly.
Why does this matter? It means you don't get access to Eloquent features like scopes.
For example, you might try this:
// inside your form request rules
'category_id' => [
Rule::exists('categories', 'id')
->active() // this scope won't work
],
That seemingly simple rule configuration will not work because Rule::exists() the query builder cannot resolve an Eloquent scope.
So what are your options?
One option is to duplicate the scope logic in the rule:
Rule::exists('categories', 'id')
->where('active', true)
->where('deleted_at', null)
// ... repeat all your scope conditions
This does work, but it is contrary to the original goal of centralizing logic in the scope in the first place.
Another option is to use a closure rule where we can access the full power of Eloquent:
'category_id' => [
function ($attribute, $value, $fail) {
$exists = Category::where('id', $value)
->active() // Now you can use scopes!
->exists();
if (!$exists) {
$fail('The selected category is not valid.');
}
},
],
Now I have to repeat some of the logic that Rule::exists gave me for free, but this isn't necessarily a bad thing.
If you're filtering with complex scopes, Rule::exists() probably isn't quite the right tool anyway.
Here to help,
Joel
P.S. I could talk about validation rules for a long time. Aaron and I wrote a whole book on the topic.