Laravel 4.x, using both controller & resource routing - laravel

I'm trying using this:
Route::resource('users', 'UserController');
Route::controller('users', 'UserController');
When I'm using one of them - WORK,
otherwise - only resource work.
There is an option to using them both?

Which ever is on-top will take priority so if you put Route::controller on-top then that's the one that would work. I would post this as a comment but I don't have the rep to do it. Also why would you wanna use both of them at the same time?

Try moving Route::controller declaration above Route::resource:
Route::controller('users', 'UserController');
Route::resource('users', 'UserController');
The thing is that Laravel tries to match request with your defined routes by going from top to bottom and stops when it finds one.
localhost/users/example in your example actually hits show method in your UserController class as explained in documentation (see Actions Handled By Resource Controller).
Therefore Route::controller('users', 'UserController'); is ignored in this case.

I believe it's only working with one because once you use Route::resource(), all routes starting with users is going to be grabbed, and since Route::resource() does not work by prepending the action with the last segement in the uri (public function getUsers()), it's failing.
With your example provided, all you should need to use is Route::controller(). If there are some cases where that won't do, before it, add whatever routes you need using Route::get(), Route::post() or Route::any()
Route::resource() and Route::controller() were I believe not designed to work together and there shouldn't be much need to actually use them together.

Related

What is the difference between those routes?

I define route for update profile logic, when I used first logic It does not work but the use of second logic works fine. So I don't know what is the difference between those.
1. Route::post('/profile', 'ProfileController#update');
2. Route::post('/profile', 'ProfileController#update')->name('profile');
The only difference between them, the name,
so If you put in form action something like {{ route('profile') }} you mean: go to route that has name profile.
Read this for more details.
Routes with name eg Route::post('/profile', 'ProfileController#update')->name('profile');
can be accessed in blade using {{route('profile')}}
whereas the other one can only be accessed using url(). e.g
{{url('/profile')}}
The second one is a 'named route'. It allows you to reference your route by a name.
Laravel 5.7 Docs - Routing - Named Routes
Well the obvious difference is the added "->name('profile')" named route to your second line. You have tagged this post with laravel-5.7 so I have linked the documentation for this version: https://laravel.com/docs/5.7/routing#named-routes
It appears to me that perhaps you have some logic in the update function of your ProfileController like so:
if ($request->route()->named('profile')) {
//
}
Which would change the outcome of the request. Hope this helps, best regards.

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.

How to exclude slugs from a Laravel route pattern

I have a Laravel Spark application, and would like to use the first two parameters in a route for team and project, with exceptions like about_us, settings, api etc.
I have set up my routes, similar to:
Route::pattern('team', '[a-zA-Z0-9-]+');
Route::pattern('project', '[a-zA-Z0-9-]+');
Route::get('/home', 'HomeController#show');
Route::group(['prefix' => '{team}'], function () {
Route::get('/', 'TeamController#dashboard');
Route::group(['prefix' => '{project}'], function () {
Route::get('/', 'ProjectController#dashboard');
...
//Spark defines routes such as /settings after the apps routing file is processed;
//thus I cannot route to /settings as it's caught by /{team}.
I am struggling to do one of two things. Either, exclude values like 'api', 'settings' etc from the {team} pattern; or get the Laravel Spark routes to run before my web routes, so that I can ensure all valid routes are checked before the catch-all of /{team}.
Any ideas would be appreciated!
One suggestion I'd have, is to consider having the prefix of teams, then the team name after, you may find you want to add more sort of catch-alls like this for another section and run into more problems down the line. Perhaps listing all the teams using the index of this closure could be of benefit to admins of the system too?
If you'd like to continue down this route, take a look in your config.app.php, I believe that switching around the following two providers may well achieve what you're after. End result order:
App\Providers\SparkServiceProvider::class,
App\Providers\RouteServiceProvider::class,
I'm using the latest version of Spark after a recent install myself, this seems to be the default now, apologies if this is a red-herring!
I appear to have solved it, using the following pattern:
Route::pattern('team', '(?!^settings$)([a-zA-Z0-9-]+)');
For those who are new to the question, the principles are as follows. In a plain Laravel installation, you could re-order your routes to ensure they are processed in the right order, putting wildcards after your fixed routes.
With Spark, there are a number of routes all encapsulated away in the Spark package. Preferring not to mess around with this, allowing for easier Spark upgrades later amongst other things, it is possible to use a route pattern to limit the acceptable values for your parameter. As such, with some Googling on RegExs, I appear to have found a pattern that will exclude slugs matched by my {team} parameter.
I believe that adding more exclusions is as easy as inserting a pipe operator.
This would also obviously work on standard Laravel installations, but re-ordering your routes is probably a better first call.
You should define the routes you want to exclude first.
Then define your patterns below them. They will have precedence over the patterns because in Laravel routes are evaluated in top to bottom order.

Laravel Controller Delegation

Trying to keep my Laravel project organized here, while letting it grow.
Currently I use:
Route::controller('/admin', 'AdminController');
...in order to allow the controller to service general admin pages. This is working fine, however I'd like to delegate specific subqueries to other controllers for cleanliness reasons.
For example, I'd like /admin/dashboard to resolve to AdminController#getDashboard. I'd also like /admin/gallery/ to resolve to AdminGalleryController#getIndex, and /admin/foo/bar to resolve to AdminFooController#getBar.
Is there a simple way to slowly expand functionality like this?
We've migrated to Laravel 5 and 5.1, and this still remains a good way to do things. If you aren't using route groups in Laravel, then you aren't doing Laravel right.
You can define those others as controller routes as well. Just do it before Route::controller('admin') because Laravel searches the registered routes in the other you define them. Since /admin/gallery would match Route::controller('admin') as well as Route::controller('admin/gallery') latter has to be defined first:
Route::controller('admin/gallery', 'AdminGalleryController');
Route::controller('admin/foo', 'AdminFooController');
Route::controller('admin', 'AdminController');
Instead of writing admin every time a route group might be a nice improvement as well:
Route::group(['prefix' => 'admin'], function(){
Route::controller('gallery', 'AdminGalleryController');
Route::controller('foo', 'AdminFooController');
Route::controller('/', 'AdminController');
});
Yes. Simply declare your "exception" routes before your main controller route.
Route::get('/admin/gallery','AdminGalleryContoller#getIndex');
Route::get('/admin/dashboard','AdminController#getDasboard');
Route::controller('/admin','AdminController');

How to check value of parameters of RESTful controller's action

I use the Larvel 4.1
If I use routes for every action I can check parameters value into route like here
Route::get('user/{id}', 'UserController#showProfile')->where('id', '[0-9]+');
But I don't understand how to check this value when I define a route for a RESTful controller
Route::controller('users', 'UserController');
Do I check parameters directly into controller's action or there is another way?
Yeah, looks like this is not the way Route::controller() works, but if you do
Route::pattern('one', '[0-9]+');
It will work. Because this is how Laravel create controller routes parameters:
GET|HEAD myactions/id/{one?}/{two?}/{three?}/{four?}/{five?}
The problem is that you cannot filter those parameters this way because they may appear in actions of different controllers. So you probably will have to create some of those routes manually:
Route::get('user/{id}', 'UserController#showProfile')->where('id', '[0-9]+');
Which, in my opinion is better than use a generic Route::controller() or Route::resource(). And in Phil Sturgeon's opinion too, as you can see in his article: http://philsturgeon.uk/blog/2013/07/beware-the-route-to-evil
So, I actually use separated routes for each action this manner
Route::pattern('one', '[0-9]+');
Route::get('user/{id}', 'UserController#showProfile');
I simple was hoped do it in more short way.

Resources