Cakephp - Foreach в контроллере, как правильно передать результат для просмотра? - PullRequest
0 голосов
/ 14 октября 2011

Это мой первый вопрос по 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'));
      }
    }

Я собираю идентификатор каждого разговора, которым владеет текущий пользователь, затем "foreach" тезисы, чтобы найти всех пользователей в этих беседах.

На самом деле это работает очень хорошо, но я нахожу решение немного грязным,Есть ли лучший способ для foreach в контроллере, а затем передать это в поле зрения лучше, чем это?

Или, может быть, мой подход очень плохой, и я должен сделать совершенно другим способом?

Редактировать:

В моей модели разговора:

    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 Ответ

2 голосов
/ 14 октября 2011

Проблема вашего подхода в том, что он будет вызывать N + 1 запросов, где N - количество разговоров. Первый запрос будет извлекать идентификаторы разговора, а затем для каждого разговора он будет получать получателей. Вы можете оптимизировать это одним из следующих способов:

  1. Используйте «Присоединиться», чтобы получить все разговоры и их получателей одновременно: http://book.cakephp.org/view/1047/Joining-tables
  2. Используйте условие WHERE ConversationUser.user_id IN (id1,id2,id3) sql во втором запросе, чтобы получить получателей для всех разговоров в одном запросе.
...