Multiple routes for the same controller function - laravel

I need to have 2 routes managed by the same controller function.
Instead of creating to different rules, I would like to create 1 rule.
So instead of something like this:
Route::get('/', ['uses' => 'MyController#index']);
Route::get('dashboard', ['uses' => 'MyController#index']);
I want to use 1 rule. I found out this multiple routes in single Route::get() call Laravel 4 but that code not works for me.
This is what I tried without success:
// THEY BOTH DO NOT WORK
Route::get('/{name}', ['uses' => 'MyController#index'])->where('name', 'dashboard|');
Route::get('/{name}', ['uses' => 'MyController#index'])->where('name', '(dashboard)?');
With these rules, if I go to / route I get 404 error.
If I go to dashboard route it works.

Making name a optional route parameter should work:
Route::get('/{name?}', ['uses' => 'MyController#index'])->where('name', 'dashboard');
Not sure why you are using uses, the shorter version would be:
Route::get('/{name?}', 'MyController#index')->where('name', 'dashboard');

Related

What does 'as' method do in Laravel

In the example from the tutorial, it shows up.
Route::group([
'prefix' => 'admin',
'as' => 'admin.'
], function () {}
Can someone tells me what 'as' does? Also, is the dot next to the 'admin' neccessary?
Thank you.
Let's say, for example, that you have this route:
Route::get('admin', [
'as' => 'admin', 'uses' => 'AdminController#index'
]);
By using as you assign custom name to your route. So now, Laravel will allow you to reference said route by using:
$route = route('admin');
So you don't have to build the URL manually over and over again in your code. You don't really need . notation if you only want to call your route admin. If you want a more detailed name of your route, lets say for ex. admin product route, then you use the . notation, like this:
Route::get('admin/product', [
'as' => 'admin.product', 'uses' => 'AdminController#showProduct'
]);
So now, you will be able to call this route by the assigned name:
$route = route('admin.product');
Update:
The previous answer I provided is valid for a single routes. For the route groups, the procedure is very similar. In the route groups you need the . notation when you add a custom name, since you will be referencing another route after that . notation. This will allow you to set a common route name prefix for all routes within the group. So by your example, lets say you have a dashboard route inside your admin route group:
Route::group(['as' => 'admin.'], function () {
Route::get('dashboard', ['as' => 'dashboard', function () {
//Some logic
}]);
});
Now, you will be able to call the dashboard route like this:
$route = route(admin.dashboard);
You can read more about this in Laravel official documentation.
you may specify an as keyword in the route group attribute array, allowing you to set a common route name prefix for all routes within the group.
For Example
Route::group(['as' => 'admin::'], function () {
// Route named "admin::"
});
UseRoute Name like {{route(admin::)}} or route('admin::')
you can use an 'as' as a named route. if you do not prefix your route name in group route than you may add custom route name like this.
Route::group(['prefix' => 'admin', 'middleware' => ['auth', 'roles'], 'roles' => ['2']], function () {
Route::post('/changeProfile', ['uses' => 'UserController#changeProfile',
'as' => 'changeProfile']);
});

Laravel 5.4 route simplification

I've been trying to find some documentation on how to accomplish the following, but it seems like maybe I'm not using the correct search terms.
I would like to implement some simplified routes in Laravel 5.4 by omitting the route name from the path – for example:
/{page} instead of /pages/{page}
/profile instead of /users/{user}/edit
/{exam}/{question} (or even /exams/{exam}/{question}) instead of /exams/{exam}/questions/{question}
Example of current routes
Route::resource('exams.questions', 'ExamQuestionController', ['only' => ['show']]);
// exams/{exam}/question/{question}
I know how to do this with route closures and one-off routes (e.g.: Route::get...) but is there a way to do this using Route::resource?
In rails the above could be accomplished with:
resources :exams, path: '', only: [:index, :show] do
resources :question, path: '', only: [:show]
end
// /:exam_id/:id
While I haven't yet found a way to accomplish my test cases using strictly Route::resource, here is what I implemented to accomplish what I was trying to do:
// For: `/{exam}/{question}`
Route::group(['as' => 'exams.', 'prefix' => '{exam}'], function() {
Route::get('{question}', [
'as' => 'question.show',
'uses' => 'QuestionController#show'
]);
});
// For: `/exams/{exam}/{question}`
Route::group(['as' => 'exams.', 'prefix' => 'exams/{exam}'], function() {
Route::get('{question}', [
'as' => 'question.show',
'uses' => 'QuestionController#show'
]);
});
// For: `/profile`
Route::get('profile', function() {
$controller = resolve('App\Http\Controllers\UserController');
return $controller->callAction('edit', $user = [ Auth::user() ]);
})->middleware('auth')->name('users.edit');
// For: `/{page}`
// --------------
// Note that the above `/profile` route must come before
// this route if using both methods as this route
// will capture `/profile` as a `{page}` otherwise
Route::get('{page}', [
'as' => 'page.show',
'uses' => 'PageController#show'
]);
No, you cannot and should not be trying to do this with Route::resource.
The whole purpose of Route::resource is that it creates the routes in a specific way that matches the common "RESTful Routing" pattern.
There is nothing wrong with wanting simpler routes (no one is forcing you to use RESTful routing), but you will need to make them yourself with Route::get, etc. as you already know.
From the documentation (not exactly your case, but related to it - showing that Route::resource is not meant to be super-configurable):
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');

Passing parameters to controller method from route in Laravel 5.5

I want to pass a parameter from my route to a controller method, to avoid duplication of code. For example, I could have my routes like this
Route::get('used-cars', array('uses' =>
'CarController#indexUsed'));
Route::get('new-cars', array('uses' =>
'CarController#indexNew'));
Route::get('new-and-used-cars', array('uses' =>
'CarController#indexNewAndUsed'));
and then have specific code for in each method for retrieving that car type. However, I would like to just have one index method in the controller, with a variable passed to it to indicate if it is a new or used car.
For example:
Route::get('used-cars', array('uses' =>
'CarController#index(1)'));
Route::get('new-cars', array('uses' =>
'CarController#index(2)'));
Route::get('new-and-used-cars', array('uses' =>
'CarController#index(3)'));
In previous versions of Laravel I believe this could be achieved using something like this
Route::get('/used-cars', array('as' => 'used-cars', function(){
return App::make('CarsController')->index(1);
}));
However I understand this was removed in Laravel 5.4. When I try it I only get class not found for the controller.
You could use a named parameter (type), and restrict that to specific values (new, used).
Route::get('{type}-cars', ['as' => 'cars.new-used', 'uses' => 'CarController#index'])->where('type', 'new|used');

LARAVEL: How to use middleware on named routes

I've been working on an app that initially didn't use middleware. Later on, I decided to add middleware and had to change my routes from something like:
Route::get('admin/poems', array('as' => 'poems', 'uses' => 'PoemsController#poem'));
to
Route::get('admin/poem', ['middleware' => 'auth', 'uses' => 'PoemsController#poem']);
Now the disadvantage is that I had been redirecting to this route (poems) several times and adding middleware as indicated will require me to go through all my code and change the name of the route in the redirect.
How do i solve this problem?
Thanks for any help.
You don't need to lose the name of your route, the array will still accept it along with your middleware.
Just add it in to look like so:
Route::get('admin/poem', ['middleware' => 'auth', 'as' => 'poems', 'uses' => 'PoemsController#poem']);
This way you don't need to go through and rename your routes anywhere and can still protect it with auth middleware.
try put middleware to a group route
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});

Nesting resource controllers with additional URL params in Laravel 5

I am trying to create routes for nested resource controllers in Laravel 5 like..
/customers/{customer}/modulename/clients/{client}
In the application I'm developing I have customers who are logging in to the application, but also sys-admins. Every customer can select multiple modules to use and within those modules there are sometimes the same models, but they're using different controllers.
I have used the following solutions, but they have some problems.
Route::resource('customers', 'CustomerController');
Route::resource('customers.clients', 'CustomerController');
I can't go for different modules in this solution, so I tried to make groups...
Route::group(['prefix' => 'customers/{customer}', ''], function(){
Route::group(['prefix' => 'module1', ''], function(){
Route::resource('clients', 'Module1\ClientAController');
});
Route::group(['prefix' => 'module2', ''], function(){
Route::resource('clients', 'Module2\ClientBController');
});
});
Route::resource('customers', 'CustomerController');
But the routes are getting annoying. When building the menu hierarchy this following route is quite difficult to create.
route('customers.{customer}.module1.clients.index');
Is what it should be, but I would like to get to go to...
route('customers.module1.clients.index');
Is there an option for the Route::group() function I'm missing or can I make a group within a route resource? Or should I just write out all the different Route::get and Route::post functions with the the $options = ['uses' => '...', 'as' => 'customers.module1.clients.*']
You can declare the following two routes:
Route::resource('customer','CustomerController');
Route::resource('customer.module.client','ClientController');
Then your routes would be like so:

Resources