3

I don't want to show the page if the ID does not exist.

How can I check this in my web.php routes in Laravel?

I currently have the following route:

Route::get('/public/{project_id}', 'ProjectController@public');

How can I do a conditional check to see if project_id exists?

I saw there was an option for Route::bind in the routing docs -- is that a solution? Thanks

Update Note: Slightly different than the Laravel 4 approach as binding seems to have been baked in to the route class.

ejntaylor
  • 1,900
  • 1
  • 25
  • 43

5 Answers5

8

What you want to use is called Route Model Binding. Laravel does what you want out of the box. If the ID is not in the database, it shows a 404 page. However, you need to change your route:

Assuming your Model is called Project, the route should look like this:

Route::get('/public/{project}', 'ProjectController@public');

And your ProjectController should look like this:

public function public(Project $project) {

This way Laravel automatically resolves the project with the ID you provide and injects it into the $project variable. If no record with the ID exists, laravel redirects to 404

Wireblue
  • 1,329
  • 1
  • 14
  • 24
Patrick Schocke
  • 1,493
  • 2
  • 13
  • 25
  • 1
    This is great. It means I can also clean my code in my controller by not using Request $request and just use the Project model straight away. Thanks for the help! – ejntaylor Jun 28 '19 at 09:49
  • But why does it have to be this way? I thought the whole Idea of mapping routes to a resource does this automatically? I am facing the same problem and I am using the ```resource()``` function to map routes to my controller functions – CliffTheCoder Mar 16 '22 at 11:09
3

Adding to Patrick Schocke's answer.

If you do not want to use Route Model Binding, you can explicitly check in the controller

public function public($project_id) {
    $projectExists = Project::where('id', $project_id)->exists();

    abort_unless($projectExists, 404, 'Project not found');

   ...
    }
}
Awais
  • 117
  • 9
Lizesh Shakya
  • 2,482
  • 2
  • 18
  • 42
  • 2
    As an alternative you can also use the Laravel `abort` helper function like so `abort(404, 'Project not found')` to remove the need to build and return the response. Or to also remove the conditional statement you might even use `abort_unless($projectExists, 404, 'Project not found')`. You can read about these more in the [Laravel Documentation](https://laravel.com/docs/5.8/helpers#miscellaneous). – Bogdan Jun 28 '19 at 09:27
  • @Bogdan Wow. Thank you so much for these tips. I was unaware of these Laravel helper functions. – Lizesh Shakya Jun 28 '19 at 09:29
  • 2
    Another option (assuming `id` was the model's primary key) would be to use `findOrFail()`. eg. `Project::findOrFail($project_id)`. This automatically returns a 404 if the item is not found. – Wireblue Jun 28 '19 at 11:30
3

Just use laravel's findOrFail() methode. This method will retrieve the first result of the query; however, if no result is found a 404 HTTP response is automatically sent.

public function public ($project_id) {
    $project = Project::findOrFail($project_id);
}

source : https://laravel.com/docs/5.8/eloquent#retrieving-single-models

Karam
  • 31
  • 1
2

You can check if project_id does not exist then return 404 error by calling abort() function.

  public function public($project_id) {
        $project_id_exist = Project::where('id', $project_id)->first();
        if(!$project_id_exist){
            return abort(404);
        }
    }
Awais
  • 117
  • 9
1

You can achieve this by using laravel route model binding functionality

your route will be

Route::get('/public/{project}', 'ProjectController@public');

your controller will be

public function public(Project $project) {
       // Do your work here using $project model
       //  If a matching model instance is not found in the database, a 404 HTTP response will automatically be generated. 
}
Lizesh Shakya
  • 2,482
  • 2
  • 18
  • 42