dsbgltg159136540 2011-10-14 10:52
浏览 15
已采纳

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

This is my first question on stackoverflow so be nice if i'm doing some mistakes. Here's my problem :

  • I'm working on a messaging system and in my inbox function i want to list every conversations owned by the current logged in user. This is not a problem but then i want, for each conversation, list every users that owns it too (= recipients).

Here is how i'm dealing with it :

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

I'm gathering every conversation's id that the current user owns then "foreach" theses ids to find every users in these conversations.

Actually it is working very fine but i find the solution a bit dirty. Is there a better way to foreach in controller then pass this in view better than this ?

Or maybe my approach is very bad and i should do in a completely other way ?

Edit :

In my Conversation Model :

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

In my Conversation controller :

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

What do you think about it ? Actually it's working really fine for me. :)

  • 写回答

1条回答 默认 最新

  • dtol41388 2011-10-14 11:15
    关注

    The problem about your approach is that it will invoke N+1 queries, where N is the number of conversations. The first query will retrieve the conversation ids, and then for every conversation it will retrieve recipients. You can optimize this by one of the following:

    1. Use Join to retrieve all the conversations and their recipients all at once: http://book.cakephp.org/view/1047/Joining-tables
    2. Use WHERE ConversationUser.user_id IN (id1,id2,id3) sql condition in the second query to retrieve the recipients for all the conversations in a single query.
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路
  • ¥15 公交车和无人机协同运输
  • ¥15 stm32代码移植没反应