Cakephp - Foreach在一个控制器中,如何正确地将结果传递给视图?

时间:2011-10-14 10:52:55

标签: php cakephp foreach cakephp-1.3

这是我关于stackoverflow的第一个问题,如果我犯了一些错误,那就太好了。这是我的问题:

  • 我正在处理消息系统,在我的收件箱功能中,我想列出当前登录用户拥有的每个会话。这不是问题,但我希望,对于每个对话,列出拥有它的每个用户(=收件人)。

以下是我如何处理它:

    function inbox()
    {
      $conversationIDs = $this->ConversationUser->find('list', array(
           'fields' => array('ConversationUser.conversation_id'),
           'conditions' => array('user_id' => $this->Session->read('Auth.User.id')),
           'recursive' => -1
       ));


      $i = 0;
      foreach($conversationIDs as $conversation)
      {
          $array = $this->ConversationUser->find('first', array(
              'fields' => array('ConversationUser.conversation_id', 'ConversationUser.user_id', 'Conversation.subject', 'User.username'),
              'conditions' => array('ConversationUser.conversation_id' => $conversation, 
                  'NOT' => array('ConversationUser.user_id' => $this->Session->read('Auth.User.id'))
              ),
              'recursive' => 1
          ));
          $result[$i] = $array;
          $i++;
          $this->set(compact('result'));
      }
    }

我正在收集当前用户拥有的每个会话ID,然后“预约”这些ID以找到这些会话中的每个用户。

实际上它工作得很好,但我发现解决方案有点脏。有没有更好的方法来预先控制器,然后在视图中传递这个比这更好?

或许我的方法非常糟糕,我应该以另一种方式做到这一点?

编辑:

在我的对话模型中:

    public function getConversations($userID)
    { 
        $conversationsIDs = $this->ConversationUser->find('list', array(
            'fields' => array('ConversationUser.conversation_id'),
            'conditions' => array('ConversationUser.user_id' => $userID),
            'recursive' => -1,
       ));

        $conversations = $this->find('all', array(
            'conditions' => array(
                'Conversation.id IN('.implode(",", $conversationsIDs).')'
            ),
            'contain' => array(
                'LastMessage' => array(
                    'User' => array(
                        'fields' => array('User.username')
                    )
                ),
                'ConversationUser' => array(
                    'User' => array(
                        'fields' => array('User.username')
                    )
                )
            )
        ));
        return $conversations;
    }

在我的对话控制器中:

    function inbox()
    {
        $conversations = $this->Conversation->getConversations($this->Session->read('Auth.User.id'));
        $this->set(compact("conversations"));
    }

你怎么看?实际上它对我来说真的很好。 :)

1 个答案:

答案 0 :(得分:2)

您的方法的问题是它将调用N + 1个查询,其中N是会话数。第一个查询将检索对话ID,然后对于每个对话,它将检索收件人。您可以通过以下方法之一对其进行优化:

  1. 使用加入一次检索所有会话及其收件人:http://book.cakephp.org/view/1047/Joining-tables
  2. 在第二个查询中使用WHERE ConversationUser.user_id IN (id1,id2,id3) sql条件来检索单个查询中所有会话的收件人。