1

I just encountered one of the limitations of the MVC architecture I'm currently using for my applications. Currently, my URLs look like this:

www.example.com/controller/action

Each request arrives at the front controller, which loads the requested controller class from the URL, and executes the action (method) of it. This works fine, until you need to start using nested controllers.

Example: There's a 'users' controller which holds methods like createUser(), editUser(), deleteUser() etc. All perfectly possible with the current URL structure... But what if we also need to manage user types? We would need a separate controller 'usertypes' which also holds methods like createUserType(), editUserType()... However, since user types are a part of users, the 'usertypes' controller should be nested inside the users controller, as this:

www.example.com/users/usertypes/addusertype

With the current URL structure however, this is not possible... How can I make use of nested (or multi-level if you will) controllers?

UPDATE: here's a basic representation of the application I'm working on: It's a basic business application for the administration department where they can add, view, edit and delete data from 3 categories (Promotions, Mailings and Cardholders). Each category represents a table in the database and has its own distinct fields. Accounts need to be created by the admin, users cannot create an account themselves and they can't consult their user profile.

For each of those categories I've made a controller, which holds actions like add(), edit(), getAll(), getSingle(), delete()... Each of those actions calls the appropriate methods from the Model and renders the corresponding View(s).

This was all possible with the current URL structure, which had URL's like:

example.com/promotions/add
example.com/promotions/getsingle?id=123

Recently they asked me to make it possible to also manage types of promotions, mailings and cardholders. Right now they already have a School Discount, a 20% Discount etc... But they want to add more as they wish.

This means i need a PromotionTypes controller, which also holds actions like add(), getAll(), getSingle(), delete()... It would be nice if the PromotionTypes controller could be nested in the original promotions controller, which enables URL's as so:

example.com/promotions/promotiontypes/add

instead of

example.com/promotiontypes/add

With my current front loader, this is not possible, since the first part of the URL automatically gets treated as the controller, and the second part as the action to execute from it.

user1440560
  • 163
  • 1
  • 7
  • You have controllers and models mixed up. All of your methods should live within models that can be accessed whenever you need them. The controllers should handle specific cases, like you've shown, but be flexible enough to use whatever methods they need from any model you want. Are you using an autoloader to load your classes/models? – Matthew Blancarte Aug 14 '12 at 23:49
  • If you separate the concept of controllers and routes, and have a configurable router that determines the correct controller and action for a given url, you don't need nested controllers. This is what the major frameworks do. – WayneC Aug 14 '12 at 23:51

2 Answers2

2

It seems like you have tied the controllers not to the view but to each domain object.

Also, what's with the strange routing? Why not :

POST "www.example.com/profile/42/type"

Because you are adding a types to the profile of specific user. This translates to execution of method postType() on the Profile controller.

If you are building your own routing mechanism, maybe this answer could be helpful.

The bottom line is this: you do not need such strange controller-of-controllers. What you need is to start looking at what sort of views you have , and then creating controller for each of them, instead of starting by looking at model layer.

Community
  • 1
  • 1
tereško
  • 58,060
  • 25
  • 98
  • 150
  • I've updated my original question with a representation of my current URL structure and front loader. Could you please have a look at it? I can't seem to understand the benefits of tying the controllers to the view... Thanks – user1440560 Aug 15 '12 at 12:12
  • @user1440560 The controllers are tied to the views to avoid exactly such misguided controller-of-controller-of-controller abominations. Also it is because of the small details that the views and controllers are of the same layer, while model is actually a completely separate layer. Then again, I am quite sure that you don't really have a view. Just a template which you call "view" for appearances sake. – tereško Aug 15 '12 at 13:13
1

You don't mention whether you are using a framework, but the normal way would be to have the "router" apply special handling to the exceptions, e.g. Zend Framework routers

cEz
  • 4,932
  • 1
  • 25
  • 38