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 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)