2
votes

Using Laravel 6, I inject a model in a controller like this :

public function edit(School $school)
{
    return view('/school/form', ['school' => $school]);
}

All is working fine when I enter an url like this :

http://localhost:8000/schools/3d537a0f-4c74-4fae-99af-6f1b2c4b34c8/edit

But if I try another url like this one (with a wrong uuid):

http://localhost:8000/schools/3d537a0f-4c74-4fae-99af-6f/edit

Then I have this PostgreSQL error :

SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for type uuid: "3d537a0f-4c74-4fae-99af-6f1b2c4b34c" (SQL: select * from "schools" where "id" = 3d537a0f-4c74-4fae-99af-6f1b2c4b34c limit 1)

Does it mean that I have to check the uuid before ? Is there any elegant way to prevent this and to have an automatic redirection to a 404 page ?

3
Thanks for this link. I think my model is well configured : public $incrementing = false; protected $keyType = 'string'; So I think the problem is not the model. - Dom
I refer to the solution of the issue: I deleted the session cache file inside storage/framework/sessions and then all back to work. I would suggest to clear the cache entirely though - Clément Baconnier
I tried to clear the cache, without success. i continue to search. - Dom

3 Answers

4
votes

In your route definition, you can use a constraint on the parameter to avoid matching:

Route::get('school/{school}/edit', 'SchoolController@edit')
    ->where('school', '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$');

This will result in a 404 because the route doesn't match invalid UUIDs. More info about this topic can be found in the documentation. There is also an explanation how to define a global constraint to avoid repeating it for every route.


For resource routes, the solution is slightly different. You will need to define a global constraint in the boot() method of your RouteServiceProvider:

Route::pattern('school', '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$');

In case your resource is called differently than your route parameter, you need to customize the parameter name when defining the route resource:

Route::resource('university', 'UniversityController', [
    'parameters' => ['university' => 'school']
]);

Note: this is just for illustration, I doubt you need it...

0
votes

yes, please check if id exits then return data else redirect to 404.

Or you can use Eloquent findOrFail method.Example:

$model = App\Flight::findOrFail(1);

this will redirect to 404 automatically if record not found.

0
votes

I believe you have an issue somewhere else that interfere somehow with the model resolution and should look deeper what the cause (like a package perhaps?).

As a workaround you can use explicit binding to prevent this error

In your RouteServiceProvider.php file

use Ramsey\Uuid\Uuid;

...

public function boot()
{
    parent::boot();

    Route::bind('school', function ($value) {
        if (! Uuid::isValid($value)) { 
            throw (new ModelNotFoundException)->setModel(School::class, $value);
        }

        return School::findOrFail($value);
    });
}

But, this is a hack only to patch an error that shouldn't be there.