-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.x] Adds support for specifying a route group controller #40276
[8.x] Adds support for specifying a route group controller #40276
Conversation
Did you test this with route caching enabled? |
@driesvints yup 👍 All worked as expected Here's output of |
I think Something like this: Route::controller(PlacementController::class, function () {
Route::get('/', 'index')->name('index');
Route::get('/bills', 'bills')->name('bills');
Route::get('/bills/{bill}/invoice/pdf', 'invoice')->name('pdf.invoice');
}); |
@mateusjunges I think because of the same reason why we don't do that in other methods: consistency. Otherwise any method on the router could have a second param as the callback with routes and that would mix things up a bit too much. |
Agreed with @driesvints. I think consistency is king here. |
Given that you've tested all other variations of route registry ( |
@koenhoeijmakers good call. I've added a supporting test. It actually wasn't supported before but is now 👍 |
hi @lukeraymonddowning , first of all thanks for this! one thing, could you add a method signature to a Route facade file? phpstan is complaining for unkown static method controller |
Using this breaks; if you're still using |
@Oluwa-Pelumi you don't need to use different syntax, just use controller as an array key rather than a method call. It works exactly the same as the other group methods 👍 |
I think I have found a bug concerning this new awesome feature. It seems the implementation has a problem with namespaced group routes. This works Route::controller(FooController::class)
->group(function () {
Route::get('/foo', 'foo');
}); This also works Route::namespace('App\Http\Controllers')
->group(function () {
Route::get('/with_namespace/bar', [FooController::class, 'bar']);
}); This throws an exception Target class [App\Http\Controllers\App\Http\Controllers\FooController] does not exist. Route::namespace('App\Http\Controllers')
->controller(FooController::class)
->group(function () {
Route::get('/with_namespace/foo', 'foo');
}); I have created an example Laravel repository with a test to reproduce the bug. |
This is not a bug, because
P.s: but why do you need to use |
This answer makes sense when you ignore the fact that the original namespace implementation without group controllers. Already only applies the namespace to routes which dont reference a full class namespace controller action. This behaviour is missing in the route group controller implementation so indeed I think this is a bug. Please look at my tests. And yeah I know this is a really special use case but this error came up in the Laravel Jetstream code base so it seems not that uncommon. |
It doesn't look like that much of a bug to me. You specified a namespace that all controllers should be prefixed with. Then you provided a controller class name as the namespace you specified was prefixed. |
I would like to add a 'where' condition like this:
Is this possible? |
@kkbt please see the docs on route groups in general: https://laravel.com/docs/8.x/routing#route-groups The answer to your question however is no, because route groups don't support the where method at the group level. It would have to be placed on a specific route. |
And it is not possible to implement this? It would be very elegant feature. |
@kkbt Skimming over the PR it seems that the new controller function is just another attribute to the RouteRegistrar. So you should be able to append your condition there instead after the group-function (which is in fact a method of the Router and does not return anything, so appending Have you tried this (Note the difference in the where function, we are passing an array here instead of two parameters)? Route::controller(FooController::class)->where([ 'id' => '[a-z]{20}' ])->group(function () {
Route::get('{id}', 'view');
Route::get('/online/{id}', 'online');
}); |
@dennisprudlo It works! Excellent. Thank you very much! |
Superb future! Thank you! A small observation: it does not work with invokable controllers though. Both of the routes below should call
Currently working workaround:
IMO, it should call the |
Howdy!
Motivation
Whilst recently working on an application with a lot of routes, I came across a situation I thought could be solved quite easily. The application has many routes that sit in groups. All routes in each group reference a different method on the same controller.
You can see here that not all methods fit in directly with CRUD. It is common that there is also a
forceDelete
anddownload
method in these groups, along with other items.Solution
I thought it would be much cleaner to be able to reference the controller just once for each group rather than repeating the same controller class over and over. With this PR, the following syntax is now possible.
I think this removes a lot of visual load from a DX perspective. It also provides a nice location to group all controller methods together in route files when not using
resource
orapiResource
.Considerations
This can be thought of a fallback; if the user specifies
@
,array
orclosure
orinvokable
syntax, the router will override the group controller attribute. None of the following examples will use thePlacementController
.For more thoughts on this, check out the comments on this tweet I put out: https://twitter.com/LukeDowning19/status/1479032102872096771?s=20
Thanks for all the hard work as always. What an awesome community to be a part of 🥳
Kind Regards,
Luke