Named restful routes in Laravel 4 - laravel

So, I've been able to get restful controllers working with
Route::controller('users','UserController');
class UserController extends BaseController {
public function getAccount(){}
}
and so /users/account works. However if I try to do something like
Route::any('account',array('as' => 'account','uses' => 'UserController#account'));
and go to /account, it doesn't work (NotFoundHTTPException). Is there a way to use named routes and restful controllers in conjunction? I like how the restful system breaks up requests, and how named routes encapsulate the URI's and decouple them from the function names. This worked in Laravel 3. Am I missing something in the syntax, or did Laravel 4 purposefully disallow this kind of mix-and-match behavior? Thanks...

This would depend entirely on the order you have defined the routes. If it's not working try reversing the order of the definitions.
But because Laravel is all about making your life easier you can pass an array of method names and their corresponding route name as the third parameter to Route::controller.
Route::controller('users', 'UsersController', ['getProfile' => 'user.profile']);
This might not directly apply to your situation but it is super handy.

Try this:
Route::get('/',array('as'=>'named_route','uses'=>'yourRestfulController#getMethod'));
This works nice for me. The trick was adding the action type after # part. You should use the full name of the method unlike in L3.

This works nice for me. The trick was adding the action type after # part. You should use the full name of the method unlike in L3.
Because REST prefix get, post, and so on are patterns to distinguish what type of REST it implements. When you named restful controllers route they didn't act like RESTful controllers anymore but a normal Controller you wish to named. Example of this:
Route::get('user/profile/', array('as'=>'dashboard', 'uses'=>'ProfileController#showDashboard'));
Consider this one:
Assuming we want SystemController to be a RESTful controller so you'll define:
Route::controller('/', 'SystemController');
Then you want to named the postDashboard on the SystemController as dashboard, so you'll modified your routes as:
Route::get('user/profile/', array('as'=>'dashboard','uses'=>'SystemController#postDashboard'));
Route::controller('/', 'SystemController');
On that scenario,postDashboard should not be access via GET protocol since we declared it to bePOST, that is if Laravel treated it as RESTful Controller, since we named it that way it will be treated as normal not RESTful, so we can access it tru GET protocol. Naming it that way will be so dramatically not appropriate, coz we are breaking what we want first which is telling Laravel to treat SystemController as a RESTful.
I think you have to consider the post of Jason Lewis as the appropriate answer. No hard feelings #arda, since you are also correct.

Related

Laravel do i need two controllers to handel two store functions?

Basically what i want to do is that 1 Controller handels two store functions called like this:
public function singleupload(){
..some code
}
and
public function multiupload(){
..some code too
}
as i continued to define the routes (get/post)
Route::get('/MultiUpload', 'controller#MultiUpload');
Route::get('/SingleUpload', 'controller#SingleUpload');
Route::post('/MultiUpload', 'controller#storeMulti');
Route::post('/SingleUpload', 'controller#storeSingle');
and as i tried to post some data to my database it tells me that there is no 'store' function. So i opened the docs and found this:
POST /photos store photos.store
So my question is can i create two store functions in one controller or do i have to create a different one so every route has its own controller with its own store function?
You are doing some things wrong.
First of all follow Repository Pattern.
You should always write all common functions in Repository which can be accessible in entire Project.
You should use controller only to fetch the request from the Route and pass all the logic to the Repository.
These Process will help you reduce all you coding lines.
Hope this helps !!!
cheers!!
NO you don't need to create new Controller. You can add new action for this.
But it also, depends on the how is your application functionality.
Normally, i personally recommended to create generic function or traits or add the functionality in base controller.
you can handle multiple store functions in one controller there is no need to create 2 different controllers.

Laravel Middleware: Where should you put it as a best practice?

I was reading the Laravel documentation about middleware and at a certain point it said: "it would be more convenient to specify middleware within your controller's constructor."
I always assigned the middleware to the routes in the routing files because it felt easier to understand which functions were affected by the middleware.
I was wondering if there was a specific reason why the documentation says to put the middleware assignments directly in the Controller constructor or if it was just a matter of preference.
Its all depends on your own choice.
I always prefer to use middleware in route as a group, which keeps things centralized and I can find them easily.
Route::group(['middleware' => ['middleware1']], function () {
// your routes under middleware1
});
Route::group(['middleware' => ['middleware2']], function () {
// your routes under middleware2
});
I think it's a matter of preference, i like to assign the middleware to the route so i don't have to exclude certain methods in the controller plus it's much easier to know which routes use the middleware just by looking at the routes file.
it is more convenient to specify middleware within your controller's constructor.
This simply means you have more control over each methods if you use it in your controller's constructor, so that you can specify certain rules in method levels.
But when you are assigning to the routes you can only control the routes rules.
Thank you for your question, as mentioned before in most cases it is a decision made by the team you are working with.
From my own personal experience, I can only explain to you why we choose to use middleware definition in routes file instead of a controller.
In large applications, there are many cases of a dozen controllers.
With that being said, there can be cases where you have to change some middleware name. If you define it on route group you would have to change only one line of code, but if you define it in a constructor you would have to go to every controller and change it.
Some companies are using controllers to inject certainly classes into it. There can be a huge amount of injecting and assigning classes in the constructor itself.
That's why defining crucial checks should not be happening on this level of code.

Is the Web API routing mechanism really smart enough to accept plurals of the Controller name?

I have a method like this in DeliveryController.cs:
[Route("api/Deliveries/Count")]
public int GetCountOfDeliveryRecords()
{
return _deliveryRepository.GetCount();
}
There are other methods with routes using "Delivery" instead of "Deliveries" which are discovered. But why is the plural of the Controller name also found? Does the Web API routing engine really look first for the API call precisely and then, if not found, look for the singular of that?
IOW, when passed "...api/Deliveries/Count" does it first look for DeliveriesController and, when not found, then search for DeliveryController?
When you apply a Route attribute directly to a method, the routing engine knows exactly what's the name of the method mapped to that route through reflection and it doesn't try to locate it based on it's name.
When using attribute routing, you can use any naming you want even if you don't respect conventions.
This route would be completely valid:
[Route("api/whatever")]
public int UnrelatedName()
{
return _deliveryRepository.GetCount();
}

Transforming action name in route declaration

I'm wondering if there is a way to declare routes in MVC3 so that the route "zone1/{controller}/{action}" would direct to {controller}.zone1{action} method and "zone2/{controller}/{action}" would direct to {controller}.zone2{action} method, for example. So that's basically transforming the target action name based on the route.
Thanks
Check out The Attribute Routing project. You can specify on your methods the routes which I feel is a bit easier to read. Here's a decent blurb on it:
http://gregorsuttie.com/2012/01/12/attributerouting-for-mvc/
You could also write your own custom route handler but I don't believe you can do what you want without some custom code. I could be wrong here though. The attribute routing project should work just fine for what you want however.

Is it possible to use T4MVC with custom routes defined in global.asax?

I'd like to be able to use T4MVC with custom routes.
Is this possible and how do I use it? I've not seen anything generated in the strong helpers to be able to do this. Since the custom routes are just strings, I don't know if this is even possible.
If by custom route you mean 'named routes', then T4MVC indeed doesn't generate anything for them, as that would require parsing your code.
Instead, the simple thing to do is to just define a public constant with the route name, and use that both in the route definition and wherever you need to refer to the named route.

Resources