Skip to content

Laravel validation rule to check if a custom route key exists.

License

Notifications You must be signed in to change notification settings

codezero-be/laravel-route-key-exists

Repository files navigation

Laravel Route Key Exists

GitHub release License Build Status Code Coverage Scrutinizer Code Quality Total Downloads

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.

Requirements

Installation

Require the package via Composer:

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:

public function getRouteKeyName()
{
    return 'id';
}

This also works when you are using a custom or computed route key in your model:

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.

Usage

Let's say you have a model with an ID of 1, but getRouteKey() returns the encoded value of 1234.

In your validation rules, pass your model's class name to \CodeZero\RouteKeyExists\RouteKeyExists:

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.

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:

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.

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:

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').

Useful Packages

Testing

vendor/bin/phpunit

Security

If you discover any security related issues, please e-mail me instead of using the issue tracker.

Changelog

See a list of important changes in the changelog.

License

The MIT License (MIT). Please see License File for more information.