Going to next matching route if no model was found - laravel

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

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

Using route actions with new laravel route syntax

I have question about syntax which I can not find an answer for.
I have code in routes file:
Route::get(
'/something/{seoString}/{someMore}',
['as' => 'my_name', 'uses' => '\my\namespace\MyController#index', 'my_route_action' => 20]
);
And I would like to rewrite it using the new syntax for calling controller
Route::get(
'/something/{seoString}/{someMore}',
[MyController#::class, 'index'] // would like to use this new syntax
);
And it works fine, but how can I add the custom route action 'my_route_action'?
I know it's possible to wrap the routes with a group and add it this way:
Route::group(['my_route_action' => 20], static function () {
Route::get(
'/something/{seoString}/{someMore}',
[MyController#::class, 'index'] // would like to use this new syntax
);
);
But that's not what I'm looking for. I don't want to be adding one group for each route just to add the route action.
So I wanted to ask if it does exist something like ->addCustomAction() or how is this supposed to be done?
Unfortunately the route action is not a thing, and probably shouldn't be. Unsure what you're actually trying to achieve with that too.
If you're passing in GET data like a bit of data, you can do it through: {variable} so the URL would become the following:
Route::get('my-route-url/{model}/get', [MyController::class, 'methodName')->name('something')->middleware(['something'])
And in your controller, you dependency inject request if you're wanting to use that too, as well as the model:
public function methodName(Request $request, Model $model)
{
dd($request->all(), $model);
}
The "as" is the the name method. Middleware is still middleware.
If you're trying to do a Key/Pair bit of data, you need to use POST request and pass it in the data, which you can access via the $request->input('keyName') method in the controller.

Route User Role Laravel 5.4

I'm very confused on this situation. I have two routes with on resource name.
Route::resource('product', 'Product\AreaManagerProductController');
Route::resource('product', 'Product\SystemAdminProductController');
I need to make it as one because I have a contextual binding.
$this->app->when(AreaManagerProductController::class)
->needs(ProductInterface::class)
->give(AreaManagerProductRepository::class);
$this->app->when(SystemAdminProductController::class)
->needs(ProductInterface::class)
->give(SystemAdminProductRepository::class);
The contextual binding works fine... but I need to change my route like this.
Route::resource('product_area_manager', 'Product\AreaManagerProductController');
Route::resource('product_system_admin', 'Product\SystemAdminProductController');
I created ProductController and some kind of weird solution.
public function index(){
//Create a conditional statement base on user
return app('App\Http\Controllers\Product\AreaManagerProductController')->index();
}
It may work but it doesn't trigger the middleware... What could be the best practice on this situation. TY
You can have your Route like this
Route::group(['prefix' => 'product', 'namespace' => 'Product', 'middleware' => '<your middleware>'], function() {
Route::resource('area_manager', 'AreaManagerController');
Route::resource('system_admin', 'SystemAdminController');
});
The reason I grouped the route is to reduce redundancy, and the reason i removed Product from the controller name is, as there is a namespace Product already, there is no need of long Class names.
If you wan to access some methods in the AreaManagerController and SystemAdminController just extend the ProductController to these Controllers.
If you want to add some specific middleware for the actions inside these controllers, I have added a middleware clause in the route group which will affect to these controllers, if not needed just remove it.
Hope this helps you.

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');
});

laravel 5.1 routes groups takes only the first controller?

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');
});

Resources