laravel 5.1 routes groups takes only the first controller? - laravel

Route::group(['prefix' => 'api'], function () {
Route::controller(null, 'BoxController');
Route::controller(null, 'CostController');
});
This is a routed group in Laravel 5.1 the urls for the first controller is working but not for the second one 'CostController'.
If I switch the lines the first one works only. I want both controllers url to be prefixed with ...api/box/ and ...api/cost/
Examples on the internet has only one controller in the group, maybe there is another syntax?
I want the urls like : ( because I work on REST application)
api/cost
api/box
not like:
api/cost/cost
api/box/box

Why are you using null for route?
If you'll use different routes, both will work:
Route::group(['prefix' => 'api'], function () {
Route::controller('box', 'BoxController');
Route::controller('cost', 'CostController');
});

Passing null as route is one thing but the main culprit is that you are passing the same route for different controllers. The solution is to use real routes for the controllers, so. i.e. box for BoxController and cost for the other. It will work correctly then
Route::group(['prefix' => 'api'], function () {
Route::controller('box', 'BoxController');
Route::controller('cost', 'CostController');
});

Related

Route Name Prefix: Why can't I use "admin.home" in Laravel 9 in grouped routes?

Route::group(['controller' => AdminController::class, 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::get('/', 'index')->name('home');
});
This is what I'm using, based on about 20-25 searches it should work, so I should be able to reach a route by using route('admin.home') in blade. However it says that admin.home is not defined.
Why is "as" nor the "prefix" not working? I honestly don't get it, I literally copy-pasted an "accepted answer"'s code and it still doesn't work...
Solution
Route::name('admin.')
->controller(AdminController::class)
->prefix('admin')
->group(function () {
// Matches the "/admin" URL
// with route name "admin.home"
// pointing to AdminController::index(...) method.
Route::get('/', 'index')->name('home');
});
Reference(s)
Route Name Prefixes
The name method may be used to prefix each route name in the group
with a given string. For example, you may want to prefix all of the
grouped route's names with admin. The given string is prefixed to
the route name exactly as it is specified, so we will be sure to
provide the trailing . character in the prefix:
Route::name('admin.')->group(function () {
Route::get('/users', function () {
// Route assigned name "admin.users"...
})->name('users');
});
Controllers
Route::controller(OrderController::class)->group(...);
Middleware
Route::middleware(['first', 'second'])->group(...);
Route Prefixes
Route::prefix('admin')->group(...);
Route Groups
Route::group(...);
Addendum
Clear/refresh your route cache if cached previously:
Terminal Command:
php artisan route:clear

Laravel routing with or without parameter in a group

For my application I am trying to create a few routes entries.
One entry to initialise the application and another for AJAX requests.
So my application should hit the initialise function if I type https.test.com/app/drive but also if I want to type some additional parameters at the end something like this: https:test.com/app/drive/specificTabA or https:test.com/app/drive/specificTabB
The problem is that when ever I type https.test.com/drive/specificTabNameA this clashes with the fetchData get route used by my AJAX call.
How can I access the initialise function when hitting this URl https.test.com/app/drive or also hitting something like this: https:test.com/app/drive/specificTabA or https:test.com/app/drive/specificTabB?
Route::group(['prefix' => 'drive'], function () {
Route::get('', 'CustomController#initialise');
Route::get('fetchData', 'CustomController#fetchData');
});
I've done some tests, and came with the following conclusion/solution:
Route::group(['prefix' => 'drive'], function () {
Route::get('fetchData', 'CustomController#fetchData');
Route::get('{param?}', 'CustomController#initialise');
});
CustomerController:
function initialise($param = null)
{
...
}
Note that by changing the order of the routes you will actually load the correct route.
When you visit /drive/fetchData it will load fetchData route
When you visit /drive/ it will load initialise route without arguments
When you visit /drive/xyz it will load initialise route with $param being xyz
Hope it helps :)
My friend I want to get your attention to Laravel docs https://laravel.com/docs/5.0/routing#route-parameters especially this one Route Parameters. You can tell router that this route can have parameter but also can not have it. Look at this example
Route::get('/{specific?}')
Now you can get this specific parameter in your Controller function after request
public function initialize (Request $request, $specific = null)
Set it default to null as this param can both be past and not, so it should have some default value.
Good luck ;)
The following should work for you:
Route::group(['prefix' => 'drive'], function () {
Route::get('fetchData', 'CustomController#fetchData');
Route::get('{path?}', 'CustomController#initialise')->where(['path' => '.*']);
});
This will allow the following path:
/drive => initialise
/drive/1 => initalize
/drive/1/2/3 => initalize
/drive/fetchData => fetchData
Adding ->where(['path' => '.*']) will route any path to initalize, e.g. /1, /1/2, /1/2/3.
If you only want to allow the path to be one level deep you can remove the where:
Route::get('{path?}', 'CustomController#initialise');

Call both middleware & controller method in a route

In my route file I can call a controller method that way
$router->get('users/{id}', 'UserController#read');
And I can assign a middleware to a route that way, according to the documentation :
$app->get('admin/profile', ['middleware' => 'testMiddleware', function () {
//
}]);
But I don't understand how I can combine both.
I tried this but it didn't work :
$router->get('users/{id}', 'UserController#read', ['middleware' => 'testMiddleware']);
Any help would be appreciated
You can do it like this:
$router->get('users/{id}', 'UserController#read')->middleware('testMiddleware');
by this way the applied middle-ware will get triggered
I just had to swap parameters to make it work :
$router->get('users/{id}', ['middleware' => 'testMiddleware'], 'UserController#read');

how to set common controller in group route

I am working on laravel but i have no idea about using route.
i used route group method but i have a question that can we use a common controller in group route
like
I have bunch of routes
Route::group(['prefix' => 'agent'], function(){
Route::get('pay', 'PaymentController#pay');
Route::get('pay/success', 'PaymentController#success');
Route::get('pay/failure', 'PaymentController#failure');
Route::get('credits', 'PaymentController#credits');
Route::get('checkout', 'PaymentController#checkout');
});
As you can see they all are using same route so is there any way to make this as dry as possible i know those are small route but when it goes long line then it become hard to understand i know it's kind of stupid question
is there any attribute like
Route::group(['prefix' => 'agent', 'controller' => 'PaymentController'], function(){
Route::get('pay', 'pay');
Route::get('pay/success', 'success');
Route::get('pay/failure', 'failure');
Route::get('credits', 'credits');
Route::get('checkout', 'checkout');
});
No there isn't any option to define default controller for a route group. But if you have resource routes then it defines all the sub routes by itself, though it's limited to only CRUD routes. You can do something like this if you're interested.
Route::group(['prefix' => 'agent'], function($controller = 'TestController#') {
Route::get('pay', $controller.'pay');
Route::get('pay/success', $controller.'success');
Route::get('pay/failure', $controller.'failure');
Route::get('credits', $controller.'credits');
Route::get('checkout', $controller.'checkout');
});

Going to next matching route if no model was found

Let's assume we have 2 such routes:
Route::get('{categoryitem}', ['as' => 'category_index', 'uses' => 'CategoryDisplayController#index']);
Route::get('{entryitem}', ['as' => 'entry', 'uses' => 'EntryController#show']);
There are no parameter constraints for parameters and 2 following route model bindings are defined:
Route::bind('categoryitem', function($slug)
{
return Category::whereSlug($slug)->root()->firstOrFail();
});
Route::bind('entryitem', function($slug)
{
return Entry::whereSlug($slug)->firstOrFail();
});
Now let's assume that URL we run is http://project/something. Is it possible to make Laravel look first in route categoryitem for something slug and in case no model is found it will look in the second route for entry with slug something? I haven't found solution for this other than adding some prefix/suffix to route
"Skipping" routes on a condition is not possible at the moment. Although there is a request on github that would allow skipping on a condition if implemented by the framework...
In the meantime you will have to write one route that catches them all. And determine inside of that route (or controller if you wish) if the item exists.
Route::get('{slug}', function($slug){
// check if categoryitem exists
// else check if entryitem exists, etc...
});
Obviously if this becomes a bit two much code move it into a controller

Resources