An alternative approach for organizing your controllers

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?

11 Comments

  1. poncho
    Posted July 4, 2006 at 4:18 pm | Permalink

    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

  2. Posted July 4, 2006 at 4:34 pm | Permalink

    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.

  3. Posted July 4, 2006 at 4:43 pm | Permalink

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

  4. nate
    Posted July 4, 2006 at 5:19 pm | Permalink

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

  5. KesheR
    Posted July 4, 2006 at 7:45 pm | Permalink

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

  6. Posted July 4, 2006 at 9:07 pm | Permalink

    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.

  7. Posted July 5, 2006 at 9:22 am | Permalink

    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 ; )

  8. Posted July 5, 2006 at 4:54 pm | Permalink

    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.

  9. Posted July 6, 2006 at 6:05 pm | Permalink

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

  10. olegs
    Posted July 8, 2006 at 7:56 pm | Permalink

    For more complex cases:

    Edit item 34 in category 12 :

    /categories/12/edit/item/34 ?

    edit category 12:

    /categories/edit/12 ????

  11. Posted July 11, 2006 at 10:36 am | Permalink

    @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


Post a Comment

Required fields are marked *
*
*

%d bloggers like this: