I'm working on an application with quite a few related models and would like to hear some opinions on how best to organize the controllers.
Here are some options I have been considering:
1) Namespace the controllers. So, for example, have a controllers/admin directory and a controllers/public directory. This seems appealing for organization but also sorta contrived since a single resource could often have actions which might sensibly belong in different directories (e.g. the show action is public whereas the create action is admin). So this would mean breaking up some of my resources into two separate controllers - one public, one admin. Seems bad.
2) Create nested resources. I've only occasionally used nested resources so it's not always clear to me when it's best to nest resources versus simply passing the data you need through the params explicitly. Does anyone has some suggestions/examples of how best to use nested resources? When is it a good idea? When is it an overkill?
3) Just leave the default scaffolded controllers alone. Create new collection/member actions where needed and use before filters to set permissions within each controller. This seems most appealing since it keeps things simple upfront. But I'm sorta nervous about things getting messy down the line as some of the controllers might start to bloat with several new actions.
If anyone with experience designing large applications could offer some guidance here, it'd greatly appreciated.
For organizing within our applications, I have done a little bit of everything depending on the situation.
First, regarding the separate controllers for admin/user functions, I will say that you probably don't want to go that route. We used authorization and
before_filter
to manage rights within the application. We rolled our own, but 20/20 hind-sight, we should have use CanCan. From there you can setup something like this (this is pseudo-code, actual language would depend on how you implemented authorization):Or at a higher level
and in your application controller
It would depend which route, but I would use that for authorization instead of splitting up controllers.
As far as name spaces vs. Nested Resources, it depends on the situation. In several of our apps, we have both. We use name spaces when there is a cause for a logical separation or there will be shared functions between a group of controllers. Case and point for us is we put administrative functions within a namespace, and within we have users, roles and other proprietary admin functions.
and then within those controllers we have a base controller, that stores our shared functions.
This provides us logical separation of data and the ability to dry up our code a bit by sharing things like the
before_filter
.We use nested controllers if there is going to be a section of code where you want some things to persist between controllers. The case from our application is our customers. We search for and load a customer and then within that customer, they have orders, tickets, locations. Within that area we have the customer loaded while we look at the different tabs.
and that gives us urls:
Other advantages we have experienced from this is ease of setting up menu systems and tabs. These structures lend themselves well to an organized site.
I hope this helps!
Also, looks like nesting resources more than one level deep is almost certainly a bad idea:
http://weblog.jamisbuck.org/2007/2/5/nesting-resources
Yeah, it's a old article, but it makes a lot of sense to me.
If anyone disagrees, I'd like to hear why.