Laravel Route Key Exists
, (*1)
Laravel validation rule to check if a custom route key exists.
Laravel's exists rule checks a database table for a column with a given value. This validation rule uses the resolveRouteBinding() method on a model to check if a given value exists., (*2)
Requirements
Installation
Require the package via Composer:, (*3)
composer require codezero/laravel-route-key-exists
Some Background Info
Laravel's implicit route model binding allows you to automatically resolve a model by type hinting it in a controller. Furthermore, you can change the route key that is used to query the database in your model:, (*4)
public function getRouteKeyName()
{
return 'id';
}
This also works when you are using a custom or computed route key in your model:, (*5)
public function getRouteKey()
{
// "encode" the route key
return "foo-{$this->id}";
}
public function resolveRouteBinding($value)
{
// "decode" the route key
$id = (int) str_replace('foo-', '', $value);
// resolve from the database
return $this->where('id', $id)->first();
}
But what if you are sending a custom key in a POST request and you want to validate it? Unlike Laravel's exists rule, this validation rule uses the resolveRouteBinding() method to check if the key is valid., (*6)
Usage
Let's say you have a model with an ID of 1, but getRouteKey() returns the encoded value of 1234., (*7)
In your validation rules, pass your model's class name to \CodeZero\RouteKeyExists\RouteKeyExists:, (*8)
request()->validate([
'model_id' => RouteKeyExists::model(Model::class),
]);
Here, model_id is the encoded value, which will be resolved using the resolveRouteBinding() method on your model. If it can't be resolved, validation fails., (*9)
Possibly, you will need the actual ID to work with when validation passes. Tack on replace() to the rule and model_id will be updated to the actual ID:, (*10)
request()->validate([
'model_id' => RouteKeyExists::model(Model::class)->replace(),
]);
$id = request('model_id'); // actual ID
If your form uses a different attribute name than your model or database, you can replace the ID and the attribute name in the process., (*11)
request()->validate([
'model' => RouteKeyExists::model(Model::class)->replace('model_id'),
]);
$id = request('model_id'); // actual ID
//$id = request('model'); // null
Or maybe you want to keep the encoded ID in the request, but add the actual ID as well. Just tack on add() and specify an attribute name:, (*12)
request()->validate([
'model_id' => RouteKeyExists::model(Model::class)->add('actual_id'),
]);
$id = request('actual_id'); // actual ID
$key = request('model_id'); // route key
Beware that attributes that are dynamically added to the request will not be included in the array that is returned from request()->validate(). You can access those via request('attribute_name')., (*13)
Useful Packages
Testing
vendor/bin/phpunit
Security
If you discover any security related issues, please e-mail me instead of using the issue tracker., (*14)
Changelog
See a list of important changes in the changelog., (*15)
License
The MIT License (MIT). Please see License File for more information., (*16)