Laravel route with & without parameter - laravel

The question might sound simple but what's the difference between those 2 routes exactly ?
why dont we need to Add parameter for the first route
Routes
Route::get('/products', [ProductController::class, 'index'])->name('product.index');
Route::get('/products/{slug}', [ProductController::class, 'show'])->name('product.show');
here in blade file
Low to High
High to Low

When you pass an array to the route helper it will try to match up the keys of that array to the route parameters (if there are any to match up), anything that isn't a route parameter gets added as a query string parameter; so that array isn't just for route parameters.

Your index route shows all elements which is not a specific element.
The show route expects a parameter to show you all details of exactly one item.

Related

Laravel - How do I navigate to a url with a parameter to left of subdirectory

I have to test this Route, but I am not sure how to navigate to it.
Route::get('/{type}/Foo/{page}/{date}', 'FooController#index');
I understand that URLs usually have subdirectories defined before the parameters in the URL.
I have worked with URLs like this example
Route::get('/Foo/{type}', 'FooController#index');
which would have an endpoint that looks like
/Foo?type=bar
Does anybody know how to test a route such as the one above?
Well i think that you need to clear out a bit the difference between route and query parameters.
In your case you are trying to use route parameters which will actually look something like:
/{type}/Foo/{page}/{date} => /myType/Foo/15/12-11-2021
Laravel considers the words inside {} as variables that you can retrieve via request so you can do something like:
$request->type
and laravel will return you the string myType as output.
In your second case that you have tried in the past you are referring to query parameters which are also a part of the $request. Consider it as the "body" of a GET request but i don't mean in any way to convert your post routes to GET :)
The thing with your second url is that:
/Foo/{type} is not similar to /Foo?type=bar
instead it should be like: /Foo/bar
In general query parameters are when you want to send an optional field most of the times in your GET endpoint (for filtering, pagination etc etc) and the route parameters are for mandatory fields that lead to sub-directories for example /Foo/{FooId}/Bar/{BarId}
The thing to remember is that you must be careful about your routes because variables can conflict with other routes.
For example a route looking like this:
Route::get('/foo/{fooId}', [FooController::class, 'getFoo']);
Route::get('/foo/bar', [BarController::class, 'getBar']);
will conflict because laravel will consider bar as the variable of the fooId so your second route can never be accessed.
The solution to this is to order your routes properly like:
Route::get('/foo/bar', [BarController::class, 'getBar']);
Route::get('/foo/{fooId}', [FooController::class, 'getFoo']);
So when you give as a route parameter anything else than bar your will go to your second route and have it working as expected.

Product And Category Separation In Route (Laravel)

I'm setting up a new route system.
Route::get('/{cat1Url}', 'CategoryController#showCat1')->name('showCat1');
Route::get('/{productUrl}', 'ProductController#showProduct')->name('showProduct');
My sef link is after "/"
But,
{{ route('showProduct',[$p->pr_url]) }}
This method not working with route name. Working only upside route.
I don't want use
"/cat/myVariable"
or
"/product/myVariable"
Can't I use route name to work this way?
What is the solution to this?
In this way, if you make a get request to /something the laravel you start from top of web.php file looking to a route that follows the pattern. Your both routes will follow that pattern, but the laravel will always, pass the first one to controller.
You have two options:
Put only one route, and inside the controller you switch to the appropriate function. But this isn't a great ideia, because this is the function of the Web.php.
Use the routes like the documentation recommend:
Route::get('/cat/{catId}', 'CategoryController#showCat')->name('showCat');
Route::get('/prod/{productId}', 'ProductController#showProduct')->name('showProduct');
and in Controller you make the appropriate handler of your Category or Product.
You will have to have a way to tell Laravel which url to be mapped to what otherwise it will always use the last defined route. So in your case calling /myVariable and /myVariable it will use the latest definition which is showProduct. The only other way is if you use regular expression to differentiate the variables. For example:
Route::get('/{cat1Url}', 'CategoryController#showCat1')
->name('showCat1')->where('cat1Url', 'cat-*');
Route::get('/{productUrl}', 'ProductController#showProduct')
->name('showProduct')->where('productUrl', 'prod-*');
This way your slugs need to start with what you define, but you cannot use just id as a numeric value for both.

Broken route in Laravel depending on where it's defined in the file

I have those routes defined in my routes/web.php :
Route::get('references/', 'referenceController#index')
Route::get('references/{reference}', 'referenceController#show')
Route::get('references/create', 'referenceController#create')
Like that, the references/create route goes to a 404 page.
If I put this route one line before, everything works fine :
Route::get('references/', 'referenceController#index')
Route::get('references/create', 'referenceController#create')
Route::get('references/{reference}', 'referenceController#show')
Then it is obviously because of the {reference} part in my route, right? But as I wanted to filter the reference perfectly, I've put a pattern in RouteServiceProvider.php. This pattern should check that my reference is a well-formed UUID :
Route::pattern('reference', '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{10}');
Miles away from the word "create", which doesn't match the pattern.
Do you know why my route is going to a 404 page depending on its position in the file?
This is how Laravel is supposed to work. It isn't very clear in the documentation though I'll admit.
Supplementing Resource Controllers
If you need to add additional
routes to a resource controller beyond the default set of resource
routes, you should define those routes before your call to
Route::resource; otherwise, the routes defined by the resource method
may unintentionally take precedence over your supplemental routes:
Route::get('photos/popular', 'PhotoController#method');
Route::resource('photos', 'PhotoController');
This is also true if you are defining non-resource routes as you noted in your example. This is because it will try to pass "create" as the id of the reference parameter in the route which of course is not valid.
Rule of Thumb
When defining routes that have the same number of url segments, always define the route that does not have a parameter variable first. The routes file will go top-down and find the first route that matches the current request.

How to use id and /route in Laravel?

I have 2 routes:
/route/{id}
/route/add
First one shows something based on id provided and second one provies form for adding news item. My problem is that when I hit /route/add it takes the add word and treats it as id for the first route.
Is there any solution for this in laravel or do I have to use different route names?
Routes work on a first-come first-served basis. The earlier routes are looked at first. Since you have a wildcard {id} on your first of those two routes, Laravel is treating add as {id} and will be passing off to that controller/closure.
You should switch the two routes around like this:
Route::get('route/add', 'Controller#method');
Route::get('route/{id}', 'Controller#method');
OR you can always add a filter to the first route in order to tell Laravel that {id} should be a number:
Route::get('route/{id}', 'Controller#method')->where('id', '[0-9]+');
Route::get('route/add', 'Controller#method');
This way, Laravel will try to match add to your {id} wildcard but it will fail because add is not a number.
Please replace the two lines:
/route/add
/route/{id}
The {id} parameter is not always expecting a numeric value. A string is also valid like "add".

how route works in laravel with parameter

Maybe this is a very basic question but,
In laravel if i use this route:
Route::get('/{campo}','ItemController#show');
and then i try to use this route
Route::get('/mondo/','ItemController#mondo');
I get simply redirect to a ItemController#show with parameter 'mondo' but I can't reach ItemController#mondo because he take mondo like a parameter. How can I let laravel know when i want he take a variable from url and when i don't?
You just have to change the order:
Route::get('mondo','ItemController#mondo');
Route::get('{campo}','ItemController#show');
Laravel takes what comes first and your {campo} route was accepting every word you had in your URL.
Just flip your order.
first route to second and second one to first one

Resources