cybercog/laravel-optimus

Validate an encoded route key

ivanvermeyen opened this issue ยท 5 comments

Hi,

Just FYI: I've put together a validation rule that uses the resolveRouteBinding() method on a model to check if a record exists in the database. Sort of like Laravel's exists rule but then model based.

https://github.com/codezero-be/laravel-route-key-exists

This works very well with the OptimusEncodedRouteKey trait. ๐Ÿ‘

Maybe this can be of use to anyone.

Hello, @ivanvermeyen.

Package you provided seems useful. Good to have it as separate package as you've done it.

So, it's validating if model exists using encoded key and overwriting this id in request with decoded one?

If I will execute:

$validated = validate([
    'article' => new RouteKeyExists(Article::class)->replace(),
]);

This will have actual Article id?

dd($validated['article']);

So much magic :}

Indeed, but you'll need extra parentheses:

$validated = validate([
    'article' => (new RouteKeyExists(Article::class))->replace(),
]);

I was in doubt if I should add an optional second constructor parameter to enable replace or add. I think it's slightly less clear, but maybe prettier to look at without those extra parentheses? I think I will add this for flexibility...

$validated = validate([
    'article' => new RouteKeyExists(Article::class, 'article'), // store the original ID in request('article')
]);

The real logic for checking if it exists is in the models resolveRouteBinding() method, like the one in your trait, so it's not tightly coupled to a single use case. :) All I'm doing is this in essence:

if ( ! $model = $this->model->resolveRouteBinding($value)) {
    return false; // validation fails...
}

And then some checks if I should replace or add the original ID to the request.

One more possible solution is static factory:

$validated = validate([
    'article' => RouteKeyExists::model(Article::class)->replace(),
]);

Or name it as you like: make or anything else. Or even this:

$validated = validate([
    'article' => RouteKeyExists::replace(Article::class),
]);

Thanks for the input!

That's also an interesting approach. Looks cleaner than newing up the rule manually.

I've added the static constructor method model(). ๐Ÿ‘

RouteKeyExists::model(Article::class)->replace()

Yeah, this one looks good. We could add suggestion for Laravel Optimus users to readme or composer.json that there is optional way to validate if encoded models are exists. But first of all I need to start using them myself. I've never done it in any production projects.