I am (re-)learning Laravel and chose to do so via an excellent YouTube video in which we built a CRUD app. The app is mostly working very well but I have had a few problems with Laravel not "seeing" some routes until I moved them around in the web.php file.
This is my current web.php file, minus comments and routes used by a second controller:
<?php
use AppModelsListing;
use IlluminateHttpRequest;
use IlluminateSupportFacadesRoute;
use AppHttpControllersUserController;
use AppHttpControllersListingController;
//Show the full set of listings.
Route::get('/', [ListingController::class, 'index']);
//Manage listings belonging to the signed-in user
Route::get('/listings/manage', [ListingController::class, 'manage'])->middleware('auth');
//Show form to create job listing
Route::get('/listings/create', [ListingController::class, 'create'])->middleware('auth');
//Store new listing
Route::post('/listings', [ListingController::class, 'store'])->middleware('auth');
//Show form to edit job listing
Route::get('/listings/{listing}/edit', [ListingController::class, 'edit'])->middleware('auth');
//Submit completed edit form to database
Route::put('/listings/{listing}', [ListingController::class, 'update'])->middleware('auth');
//Delete listing from database
Route::delete('/listings/{listing}', [ListingController::class, 'destroy'])->middleware('auth');
//Show a single listing
Route::get('/listings/{listing}', [ListingController::class, 'show']);
My original web.php was exactly the same as this except that the ‘/listings/manage’ route, currently the second in the list, was last. When that happened, every time I tried to invoke the /listings/manage route, the Clockwork browser extension indicated a 404 error and apparently indicated that it was trying to execute the show() method of the ListingController, rather than the manage() method. I was absolutely baffled by this and only eventually solved the problem by moving the /listings/manage route higher up in web.php.
On further testing, I’m finding that I now have the same problem when I’m trying to invoke the destroy() method to delete a listing from the database. Again, I get a 404 error and Laravel seems to be trying to execute the show() method if I am reading Clockwork correctly.
I really don’t understand what is going on here with both cases. I could possibly solve the problem by moving the route that is trying to do the destroy() but I don’t understand why I’m having the problems in the first place so I want to resolve that FIRST.
Can anyone enlighten me on this matter? I’m particularly curious how Laravel resolves the last three routes in the current web.php since they have the exact same URL, /listings/{listing}, so I’m wondering how it knows whether to invoke update(), destroy() or show().
UPDATE: To the anonymous individual who thought that the post he/she cited completely answered my question, it didn’t. It didn’t explain why the last three of my routes, which have an identical path, were apparently not the source of my problem. It also didn’t give as complete a discussion of the possible solutions as some of the other answers I’ve obtained.
3
Answers
In carefully considering the answers I was given to my question, plus the older answers to similar questions, I've come up with a slightly different solution to my problem that seems to work fine. I'm posting it here now for two reasons:
Here is my revised web.php with several routes added and several of the existing routes commented out:
I left the sequence of routes/functions the same but I could have changed it around as much as I like and still be confident that it would work. Basically, whenever the path had a parameter in it, I put the parameter last and preceded it with the name of the function that would be executing in the Controller. That ensured that every route (except '/') started with the Controller name, listings, followed by the function name, and possibly followed by a parameter if it was a specific listing, so that there could never be any confusion over which function the route was going to invoke.
Some routes didn't have to change at all because they already followed the pattern, namely /listings/manage and /listing/create. One route, '/', had a second route added for /listings/index because that's what is really being done; I just keep the '/' route as a reasonable default behaviour in case the user doesn't know what naming convention I am using for the routes and tries '/'.
Is that approach likely to bite me later in ways I haven't anticipated yet?
You have these to routes:
laravel starts from first line of the script
and if requested path matches any route return it.
So suppose the request
/listings/manage
.Laravel routing engine starts from first line of web.php .
First arrives to
show
method. Request matches it!!The
{listing}
parameter could be anything evenmanage
so routing engine stops here and return theshow
method. Not checking other routes to find more compatible route.If you put the
manage
route at top ofshow
so routing engine first arrives to it and matches to it and return it.Laravel differs in the same routes by their request methods.
let’s suppose the same path is defined in 3 routes but they have different request methods.(post,put,get).
The laravel get the path and match the request method and call that route.
for more accuracy you may use the names of the routes. As: