An alternative approach for organizing your controllers

Published on and tagged with cakephp  ideas

The recommended way to organize your controllers in a CakePHP application is to group functions related to one model in a controller, like UsersController, ProjectsController, and so on. So you get urls like /users/edit/1 and /projects/show/1. That works fine, but there is a little issue. If you compare the urls with the natural language, such urls are not that easy to read. We can translate them to: “From the users edit the one with id 1” or “From the projects show the one with id 1”. But that is not the way we usually speak. We say “Edit user 1” or “Show project 1”. So it would be nice to have similar urls: /edit/user/1 and /show/project/1.

A possible solution is to group similar actions in a single controller. There would be an EditController with user() and project() functions for editing the respective models, and a ShowController with the same functions for showing the models. With some imagination you will see that this approach is similar to the command pattern.

What do you think about such an approach? Is it just a crazy idea on a hot summer day?

13 comments baked

  • poncho

    You have a good point there, I’ve often wondered about alternative URI formatting. For instance, I’d much rather have “/users/{username}/edit” than “/users/edit/{username}”.

    For small-scale projects I would recommend just using routes to achive your goal though.

    $Route->connect(‘edit/user’, array(‘controller’ => ‘users’, ‘action’ => ‘edit’));

    Cheers;
    Poncho

  • Mladen Mihajlovic

    I must admit that I’ve used routes to do just that in a couple of instances. Thing is I like having all the actions for one entity in it’s own controller.

  • drypek

    i think you should use ROUTE’s to customize your URL’s

  • nate

    Actually, any one of those scenarios is possible to do with routes.

  • KesheR

    Mmmmm I like the way it is, I don’t need it :)

  • Brandon Pearce

    One other issue is that if all you’re doing is updating a single table, then you really don’t need a separate edit() function for each model. Kind of like scaffolding, I have a save() function in app_controller that I use to save all my models unless there is something special I need to do. With this new suggestion, I would need to create an extra function to save every model even if it uses the same code as another model. (True I could just call the other function, but it’s still extra code).

    Fun to think about, though. Thanks for the idea.

  • Felix Geisendörfer

    I sometimes feel like messing with the url’s as well, in fact right now I’m working on a UrlAlias Model that’ll be released soon.

    Most of the times I feel the most flexible approach is to modify the $from_url variable in the routes.php. So in this case you would explode the $from_url on ‘/’, check if a controller with the name second item of the resulting array exists, and if this controller has an action named like the first item of the array. If that’s the case you simply switch those two arguments in your $from_url, and voilá you got yourself a new url convention.

    I think using something like an EditController would be a rather confusing setup, but well, it might offers some other advantages like better refactoring of edit related code, who knows.

    Just my ideas ; )

  • uzyn

    Very interesting idea.

    But wouldn’t that means breaking the MVC model? I admit I did think about the same issues as well, but usually I would simply use routing for that.

    But interesting idea anyway. Gives a different perspective to the whole MVC.

  • cakebaker

    @all: thanks for your comments and ideas. I will keep experimenting :)

  • olegs

    For more complex cases:

    Edit item 34 in category 12 :

    /categories/12/edit/item/34 ?

    edit category 12:

    /categories/edit/12 ????

  • cakebaker

    @olegs: I am not sure what you mean with your comment. According to my statements in this post the urls would look like:

    /edit/item/34/category/12

    and

    /edit/category/12

  • Roger Lancefield

    In my view, if you are changing the structure or organization of your application for valid architectural/design philosophy reasons, that’s one thing, but to do so just to achieve prettier URLs is allowing the tail to wag the dog. That is, by all means adopt the command pattern if it’s useful, but not to prettify URLs! To do so would be altering the inherent design philosophy of your application for the most trivial reasons. An application’s design should aim to achieve modularity, clarity, coherence, maintainability, performance, etc. etc. but not to churn out easy to read URLs. That’s why the gods gave us mod_rewrite isn’t it? :)

    Another point, it’s worth bearing in mind that not all natural languages use the SVO (subject-verb-object) syntax that English uses. E.g. for speakers of Japanese, Tibetan, Turkish and Navajo, /users/edit should look just fine. More good reasons why URL structure should ‘float free’ from application design methinks.

    Anyway, great CakePHP blog. Cheers!

  • cakebaker

    @Roger: Thanks for your comment.

    Yes, you are right, it is a bad idea to design an application only for providing nice urls. But if you think this idea further, you will end up with a “perfect” system, at least in theory. Each controller would have just one method which handles the respective action for all models. And as the framework would provide the actions for crud operations, you would have to write much less code…

    But back to reality. Yes, you are right, something like /edit/user/1 wouldn’t be natural for all languages.

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License