Model view controller 尝试制作瘦小控制器的指南&;CakePHP中的fat模型

Model view controller 尝试制作瘦小控制器的指南&;CakePHP中的fat模型,model-view-controller,cakephp,Model View Controller,Cakephp,我对蛋糕和MVC都是新手。我想从一开始就养成好习惯。其中的好习惯是保持控制器的瘦,使模型肥胖。但对于像我这样的傻瓜来说,这是一个移动的目标。如果我需要将信息从一个模型传递到另一个模型,我是否需要将所有信息转储到控制器中?试着让它在模型中工作 这里有一个动作,是我试图解决的困惑的一个主要例子 一切似乎都应该在控制器中,但我可能错了。此操作获取成员列表,并将其发送到视图。在视图中,我可以勾选我想要“激活”其帐户的成员。没有ACL,只有简单的身份验证。我确保“子管理员”只看到允许他们使用db字段cli

我对蛋糕和MVC都是新手。我想从一开始就养成好习惯。其中的好习惯是保持控制器的瘦,使模型肥胖。但对于像我这样的傻瓜来说,这是一个移动的目标。如果我需要将信息从一个模型传递到另一个模型,我是否需要将所有信息转储到控制器中?试着让它在模型中工作

这里有一个动作,是我试图解决的困惑的一个主要例子

一切似乎都应该在控制器中,但我可能错了。此操作获取成员列表,并将其发送到视图。在视图中,我可以勾选我想要“激活”其帐户的成员。没有ACL,只有简单的身份验证。我确保“子管理员”只看到允许他们使用db字段client_id管理的用户。我使用的两个模型是User和client

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%。

我想你不想只得到一个客户吧

$members = $this->User->Client->find('first', array
我想这些应该都找到了。我改进了这一点,在有大量用户的情况下使用分页。我可能错了,但通过查看此代码,您的关联和真正的目标对我来说都不清楚。例如,我不知道票证模型是如何与任何其他数据关联的。但我猜您使用的是Controller::uses,您不应该这样做,而是应该通过关联访问相关模型

不要使用像$a这样糟糕的变量名,这太糟糕了,没有人会知道在更大的代码块或应用程序中这意味着什么。您还将包含客户端数据的数组命名为$members,为什么不命名为$clients?阅读本文:对于CakePHP,我建议您遵循以下步骤

描述一下目标,我认为这可以重构得更好。如果您想激活客户端以访问票证(看起来就是这样),为什么您没有在票证或客户端控制器/模型中这样做

此外,如此大量的内联评论只是造成了更多的混乱,而不是它的帮助。写一段清晰易读的代码,代码就会自己说话。你没有做过任何超复杂的代码或超复杂的数学。同样,我可以建议您阅读“干净的代码”,我认为这是每个开发人员的“必读”

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

通过身份证也可以减少更多,但是,嘿,现在已经晚了。:)把这看作是对代码的粗略重构,想想我改变了什么,更重要的是为什么


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

里面有个笑话。。。你找到了!谢谢你!你是对的,我用$uses来买票,而不是联想。。。我觉得这可能有点太骗人了。我为此添加了注释,但我同意:好的代码就是自我注释。我只需要找到一个客户机,因为我只查找属于给定客户机的记录,而不是多次。无论如何,再次谢谢你!Cake将根据需要自动加载模型,但使用“uses”时,即使此时不需要,也会加载模型。如果你认为我是对的,你介意把答案标为正确吗?谢谢!;)当然只是想知道,你为什么建议使用分页器?另外,我的假设是,如果我的票证模型与我的用户模型相关联,我可以简单地从我的用户模型内部执行$this->Ticket?我解释了为什么我建议这样做:我不知道你的应用程序,也猜不出你将拥有多少用户。因此,如果您不想在页面上显示1000个用户,请使用分页,如果不想简单地将代码更改为使用find('all');然后,您可以在模型中获得更多的代码。如果票证与用户关联,则可以。阅读你可以通过关联链深入到你想要的深度。