MVC Putting an action in the most appropriate corr

2019-05-17 23:58发布

I was just wondering what the best practice approach is for deciding where to create an action/view in certain situations.

If User hasMany Video

where is the best place to create the action/view to show user videos?

So within the Users account page 'My Videos' link do you

  1. just create a users/my_videos action and view.
  2. create videos/my_videos action and view.
  3. or as is most likely you would already have a Controller/Action of videos/index which would have search functionality. Simply use this passing in a user id.

Any thoughts/advice greatly appreciated

Thanks

Leo

5条回答
你好瞎i
2楼-- · 2019-05-18 00:46

As always with code you have the two extremes of:

1) Putting everything in a single controller

2) Having every action in a separate controller

The ideal approach will nearly always be somewhere between the two so how to decide what is grouped together and what is separated?

In MVC I tend to look at the Views and see what the commonalities are: as you point out Users have a ref to a collection of Videos in the Model, but would you want both sets of Data in any single View? i.e. In this example is it likely that you would be on a page that both managed user details, and displayed the list of vids? If not then I'd suggest separate controllers.

If either controller would then be extremely simple - e.g. one method, then may be worth considering merging the two.

查看更多
Rolldiameter
3楼-- · 2019-05-18 00:55

My take is that it depends on the responsibility you assign to the controllers.

I would say that something like a User or a Video controller should be concerned with only those entities.

You may want to consider something like a UserDashboard (or something similar but appropriately named) as alluded to by Dunhamzzz in the comments. This can aggegate all the functionality from an "entry" point-of-view. The same way a banner / shortcut / action menu would work.

Your UserDashboard would use whatever data layer / repository is required to get the relevant data (such as the IVideoRepository or IVideoQuery implementation).

Usually when something doesn't feel right it isn't. Try splitting it out and see how it works. You can alsways re-arrange / refactor again later.

Just a thought.

查看更多
时光不老,我们不散
4楼-- · 2019-05-18 00:57

I don't think there's a 'one-rule-fits-all' solution to this question, but I would try to take an approach in which you would determine what the main object is that you're dealing with, and adding the action/view to that object's controller.

In your example I'd say that your main object is a video and that the action you're requiring is a list of video's filtered by a specific property (in this case the user's id, but this could very well be a category, a location, etc.).

One thing I would not do is let your desired URL determine in which controller you put your functionality. URLs are trivially changed with routes.

查看更多
SAY GOODBYE
5楼-- · 2019-05-18 01:02

I like to keeps things separate.

What I'd do is an index action in videos controller, passing user's id as argument and then displaying only current users video.

public function index($id = null){
   $this->paginate = array( 'conditions'=> array('Video.user_id' => $id));
   $this->set('videos', $this->paginate());

}
查看更多
手持菜刀,她持情操
6楼-- · 2019-05-18 01:05

One potential option is to do the following:

Since the videos likely have much more code around them than a simple which user has which videos lookup the video list action should be in the VideosController.

In past projects I have (in CakePHP 1.3) used prefix routing to address some of this.

In config/core.php make sure you enable routing.prefixes to include a 'user' prefix.

<?php
    ... in routes.php ...
    Routing.prefixes = array( 'user' );
?>

In the videos controller make an action with the following signature:

<?php
    ...
    public function user_index( $userID = null ){
        ...
    }
?>

and in the views where you link to the list of users videos the html::link call should look similar to the following:

<?php
    ...
    echo $this->Html->link( 'User\'s Videos', array(
        'controller' => 'videos',
        'action' => 'index',
        'prefix' => 'user',
        $this->Session->read( 'Auth.User.id' )
    ));
?>

Of course this assumes you are using the Auth component here to track the logged in user. The Session helper code to read the authenticated user id might need tweaking.

This lets you a) Not worry too much about routing aside from enabling prefix routing and b) will quickly let you have pretty links like so -- site.com/user/videos/index/419

Couple this with some Slug love ( this is the best link for this I have seen - no slug field required on the db layer - http://42pixels.com/blog/slugs-ugly-bugs-pretty-urls )

You could even end up with urls like so quite easily: site.com/user/videos/index/eben-roux

and with just a tiny bit of editing to app/config/routes.php you could eliminate the /index/ portion and the results would be SEO friendly and user friendly in the format: site.com/user/videos/eben-roux

http://book.cakephp.org/view/945/Routes-Configuration

查看更多
登录 后发表回答