Controllers, Routes For Dependent Objects

I’m looking for best practices for designing controllers and routes of dependent objects.

Using Post and Comment models from Blog demo, for example, where each Comment belongs one Post. Is it best to organize Comment actions in the Post controller, e.g., actionListComments, actionAddComment, actionUpdateComment, with routes like /post/1/comments, /post/1/addComment, /post/1/comment/2 ?

In general, would a dependent object’s actions be handled by the parent object controller?

It is pretty much up to you, how would you like your URLs to look like?

Controllers are main part of application, as they’re doing all the hard job here. But, on the other hand, it is nothing else than just translation of your route (URL) to run proper controller with proper action. So you, as application developer / designer, decide whether you want comments to be controlled by the same controller, as you use for posts or whether to implement a separate controller for this task?

For example, in base Yii demo app, login and logout actions are handled by default, SiteController. I don’t like neither naming main controller “Site” nor using it to control user-related operations. So first thing, what I do in each new app is to rename SiteController to MainController and to extract login and logout actions out of it to a fresh new UserController (actually I don’t do this each time, I have it already implemented in my base app, from which I start each my project, but you get the point).

BTW: I think you misunderstood the idea of controller, action and parames in router. You can’t have route like you showed in question. I.e.: “/post/1/addComment” or “post/1/comment/2”. It has to be always: controller/action/params. So, in your case: “/post/addComment/1” or “post/comment/1/2”.

Since you’re passing two params (variables) in second part, your URL starts to look a little bit odd, and it is open for an ease mispelling. For this purpose, consider changing your urlManager configuration in your main application configuration file to something else.

For example, I always use it configured like this:


'components'=>array

(

    'urlManager'=>array

    (

        'urlFormat'=>'path',

        'showScriptName'=>false,

        'urlSuffix'=>'.html',

        'rules'=>array

        (

            '<controller:\w+>/<id:\d+>'=>'<controller>/view',

            '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',

            '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',

        )

    ),

Plus, I’m creating a .htaccess file (or adding these lines to existing one) in root application folder (not to confuse with the one in /protected folder!) containing these:


Options +FollowSymLinks

IndexIgnore */*

RewriteEngine on


# If file or folder exists -- use it directly...

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d


# ...otherwise redirect to index.php

RewriteRule . index.php


DirectoryIndex index.php

Options -Indexes

As I result, I’m getting URLs like:


main/show.html?page=markdown-block

which could be, in your case/example like this:


post/addComment.html?post=1

post/showComments.html?post=1

post/showComment.html?post=1&comment=2

BTW: Since comments usually have key column autoincremented and numbered completely in no relation to key column for posts, you actually could achieve above with just:


post/showComment.html?comment=2

You don’t need post ID of post to which particular comment belongs, to just show only that comment. Even more, if your model relations are designed correctly, you can read parent post ID from each comment, from it’s relation, having only that commend ID passed in URL.

Overall summary and some answer to your question: For me most important element is a "piece of data", that is: a model. In blog demo posts are handled by different model than comments. Both posts and commens have different model, and so they should have separate controllers. That is my opinion.