指导试图制作瘦小的控制器& CakePHP中的胖模型

时间:2012-04-27 00:18:15

标签: model-view-controller cakephp

我是Cake的新手,也是MVC的新手。我想从一开始就养成良好的习惯。良好的习惯包括保持控制器精益,并使模型变胖。但对于像我这样的菜鸟来说,这是一个移动的目标。如果我需要将信息从一个模型传递到另一个模型,我是否只将所有信息转储到控制器中?试着让它在模型中工作吗?

这是一个动作,是我正在努力解决的那种混乱的一个主要例子。

所有似乎就像应该在控制器中一样,但我可能错了。此操作获取成员列表,将其发送到视图。在视图中,我可以勾选我想要“激活”其帐户的成员。没有ACL,只需简单的身份验证。我确保“sub-admins”只能通过使用db字段client_id来查看允许他们管理的用户。我正在使用的两个模型是用户和客户。

public function activate() {
    if ($this->request->is('get')) {
        $id = $this->Auth->user('id');
        $this->User->id = $id; //make sure current User is the logged in user
        $currentClient = $this->User->field('client_id'); // get client_id based on logged in user
        $members = $this->User->Client->find('first', array( // find users that have the same client_id
            'conditions' => array('id' => $currentClient),
            'recursive' => 1
        ));
        $this->set('clients', $members); // send the users to the view                  
    } else if ($this->request->is('post') || $this->request->is('put')) {
        $members = $this->request->data['Members']; // grab players submitted from push form
        $memberIds = array(); // this will hold the selected users
        foreach($members as $a){
            $memberIds[$a['id']] = $a['id']; // loop over user's that were selected
        }
        $usersToActivate = $this->User->find('all', array( //find user records, based on the array of id's
            'conditions' => array(
                "User.id" => $memberIds
            )
        ));
        $this->Ticket->bulkActivate($usersToActivate); // send array of members into model for processing
        $this->Session->setFlash('Activations sent.', 'default', array('class' => 'success'));
        $this->redirect(array('action' => 'index'));
    }
}

在我看来,它看起来并没有太大的错误...而且我已经在模型中进行了一些处理(如实际获取用户记录的bulkActivate所见,并生成激活票据。)

但我不禁觉得它还不是100%。

1 个答案:

答案 0 :(得分:2)

我认为你不想只获得一个客户?

$members = $this->User->Client->find('first', array

我想这应该找到所有。在有很多用户的情况下,我已经改进了这个以使用分页。我可能错了,但通过查看此代码,我的关联和真正的目标都不清楚。我不知道Ticket模型是如何与任何其他数据相关联的。但我猜你正在使用Controller :: uses,你不应该这样做,而是通过他们的关联来访问相关的模型。

不要使用像$ a那样可怕的变量名称,只是糟透了,没有人会知道在更大的代码块或应用程序中这意味着什么。您还命名了一个包含客户数据$ members的数组,为什么不是$ clients?阅读本文:Clean Code,对于CakePHP,我建议你遵循CakePHP coding standards

描述目标,我认为这可以进行更好的重构。如果要激活客户端以访问故障单(这就是它的样子),为什么还没有在故障单或客户端控制器/模型中完成它?

此外,大量的内联评论只会导致更多的混乱而不是它的帮助。编写干净且可读的代码,代码就能说明问题。你没有做过任何超级复杂的代码或超级复杂的数学。同样,我可以建议您阅读“清洁代码”,在我看来,每个开发人员都必须“阅读”。

<?php
    // UsersController.php
    public function activate() {
        if ($this->request->is('post') || $this->request->is('put')) {
            $this->User->activate($this->request->data);
            $this->Session->setFlash('Activations sent.', 'default', array('class' => 'success'));
            $this->redirect(array('action' => 'index'));
        }

        this->Paginator->settings['Client'] = array(
            'conditions' => array('id' => $this->Auth->('current_id')),
            'contain' => array(
                'OnlyModelsYouNeedHere'));
        $this->set('clients', $this->Paginator->paginate($this->User->Client)); 
    }
?>

<?php
    // User.php - the model
    public function activate($data) {
        $memberIds = array();
        foreach($data['Members']members as $member) {
            $memberIds[$member['id']] = $member['id'];
        }
        $usersToActivate = $this->find('all', array(
            'conditions' => array(
                'User.id' => $memberIds)));
        return $this->Ticket->bulkActivate($usersToActivate);
    }
?>

传递ids也可以减少更多,但是,嘿,现在已经很晚了。 :)把它作为你的代码的粗略重构,并考虑我已经改变了什么,更重要的是为什么。

如果你想看到瘦的控制器和胖模型check our plugins的正确例子,用户插件UsersController和Model可能会给你一个更大的画面。