0

How can I validate {id} to be greater than zero in the following route?

Route::get('/posts/{id}/show', [PostController::class, 'show'])->whereNumber('id');
max256
  • 35
  • 3
  • 8
  • 1
    You could also do `posts/{post}/show`, then have `public function show(Post $post)` in your Controller, and navigating to `/posts/0/show` would be an automatic 404: https://laravel.com/docs/9.x/routing#route-model-binding. – Tim Lewis Nov 15 '22 at 19:35

1 Answers1

2

Following the Laravel 9.x documentation, you should be able to do this:

Route::get('/posts/{id}/show', [PostController::class, 'show'])
    ->where('id', '([1-9]+[0-9]*)');

You can see that regex works for number >= 1: https://regex101.com/r/MFxO2h/2


Checking the source code, you can see that whereNumber is number >= 0, that is why 0 works.


As @TimLewis commented, you can also use Model Binding, it will automatically try to check if a model you want exists with the parameter ID on the route.

In your case, let's assume {id} is a Post's ID, so your Route would be like this:

Route::get('/posts/{post}/show', [PostController::class, 'show']);

Then, your controller:

public function show(Request $request, Post $post)
{
   // ...
}

If no {post} (id) matches a Post's ID, then 404, else the controller correctly executes the methods show.

matiaslauriti
  • 7,065
  • 4
  • 31
  • 43
  • Thank you for your reply. Your regex does not match with some ids. I tried 100, 1000, 10000,... and I got 404 error response. – max256 Nov 15 '22 at 19:52
  • 1
    @max256 that is true, I confused a `?` with `*`, check the answer again and try it out – matiaslauriti Nov 16 '22 at 01:28
  • yeah, it works now, but please note that we can not still use it to check ids because it could match numbers bigger than maximum size of INT and BIGINT. I wish laravel had some build-in methods for checking ids, like whereId() and whereBigIntId(). – max256 Nov 16 '22 at 05:43
  • You can check if a model exists, I am not sure about what you are doing with that ID, but as @TimLewis mentioned, you can use [Model Binding](https://laravel.com/docs/9.x/routing#route-model-binding). Check my updated answer about that, if it works, please mark the answer as correct – matiaslauriti Nov 16 '22 at 12:21