CakePHP отображать пользовательские поля из массива - PullRequest
0 голосов
/ 04 декабря 2010

Я знаю, что название не описывает лучшее, чего я хочу достичь, но я не мог придумать ничего другого.

Допустим, у меня есть следующий массив:

[Sender] => Array
            (
                [0] => Array
                    (
                        [id] => 1
                        [username] => admin
                        [PrivateMessagesUser] => Array
                            (
                                [id] => 1
                                [private_message_id] => 1
                                [sender_id] => 1
                                [recipient_id] => 3
                                [sender_status] => 1
                                [recipient_status] => 0
                                [random_key] => 
                            )

                    )

                [1] => Array
                    (
                        [id] => 1
                        [username] => admin
                        [PrivateMessagesUser] => Array
                            (
                                [id] => 3
                                [private_message_id] => 1
                                [sender_id] => 1
                                [recipient_id] => 2
                                [sender_status] => 1
                                [recipient_status] => 0
                                [random_key] => 
                            )

                    )

            )

Я использую ContainableBehaviour, чтобы отрезать лишние данные.Моя проблема: как отфильтровать Sender s после ключа, который присутствует в PrivateMessagesUser?Скажем, мне нужно только Sender, где PrivateMessagesUser.recipient_id = 3.Я пытался с

'Sender' => array( 
 'PrivateMessagesUser' => array(

 )
),

, но это не сработало.Похоже, мне нужно как-то перебрать клавиши [0], [1] ... и я не знаю как.

Любая помощь будет признательна!

РЕДАКТИРОВАТЬ

Вот как я могу получить размещенный выше массив:

$this->paginate = array(
        'conditions' => array(
            'PrivateMessage.id' => $this->__getUserPrivateMessagesInbox()
        ),
        'contain' => array(
            'Sender' => array(
                'fields' => array('id', 'username'),
                'PrivateMessagesUser' => array(
                    'fields' => array('PrivateMessagesUser.id')
                    //'conditions' => array('PrivateMessagesUser.recipient_id' => $this->Auth->user('id'))
                )
            ),
            'Recipient' => array(
                'fields' => array('id', 'username'),
                'conditions' => array('Recipient.id' => $this->Auth->user('id'))
            )
        )
    );

Как мне отредактировать эти строки для достижения желаемого результата?

РЕДАКТИРОВАТЬ 2

Я вызываю paginate () из PrivateMessagesController.

Ассоциации:

Модель пользователя:

var $hasAndBelongsToMany = array(
    'PrivateMessageSent' => array(
        'className' => 'PrivateMessage',
        'joinTable' => 'private_messages_users',
        'foreignKey' => 'sender_id',
        'associationForeignKey' => 'private_message_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'PrivateMessageReceived' => array(
        'className' => 'PrivateMessage',
        'joinTable' => 'private_messages_users',
        'foreignKey' => 'recipient_id',
        'associationForeignKey' => 'private_message_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    )
);

Модель PrivateMessage:

var $hasAndBelongsToMany = array(
    'Sender' => array(
        'className' => 'User',
        'joinTable' => 'private_messages_users',
        'foreignKey' => 'private_message_id',
        'associationForeignKey' => 'sender_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
    'Recipient' => array(
        'className' => 'User',
        'joinTable' => 'private_messages_users',
        'foreignKey' => 'private_message_id',
        'associationForeignKey' => 'recipient_id',
        'unique' => true,
        'conditions' => '',
        'fields' => '',
        'order' => '',
        'limit' => '',
        'offset' => '',
        'finderQuery' => '',
        'deleteQuery' => '',
        'insertQuery' => ''
    ),
);

PrivateMessagesUser Модель:

var $belongsTo = array(
    'PrivateMessage' => array(
        'className' => 'PrivateMessage',
        'foreignKey' => 'private_message_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    ),
    'Sender' => array(
        'className' => 'User',
        'foreignKey' => 'sender_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    ),
    'Recipient' => array(
        'className' => 'User',
        'foreignKey' => 'recipient_id',
        'conditions' => '',
        'fields' => '',
        'order' => ''
    )
);

И таблицы базы данных выглядят так:

  • users: id, username,...
  • private_messages: id, subject, ...
  • private_messages_users: id, private_message_id, sender_id, recipient_id,status, ...

Ответы [ 2 ]

2 голосов
/ 04 декабря 2010

Для этого есть три способа.

Глядя на ваш возвращенный массив данных, я предполагаю, PrivateMessagesUser принадлежит Sender.

1. Запрос модели PrivateMessagesUser

Иногда все, что нужно, это запросить правильную модель. Вы можете применить условия непосредственно к модели, к которой вы хотите применить ваши ограничения.

$this->Sender->PrivateMessagesUser->find('all', array(
    'conditions' => array('PrivateMessagesUser.recipient_id' => 3),
    'contain' => array('Sender')
));

2. Применение условий к родственным моделям

Это не всегда работает, потому что генерация SQL в CakePHP не всегда работает так, как вы этого хотите. Но в простых случаях, таких как отношения hasMany, вы можете использовать это:

$this->Sender->find('all', array(
    'conditions' => array('PrivateMessagesUser.recipient_id' => 3),
    'contain' => array('PrivateMessagesUser')
));

Опять же, это будет работать, только если Cake выполняет JOIN для параметров Containable и правильно использует условия.

3. Использование объединений

Этот метод является надежным, но немного грязным, поскольку его можно легко настроить.

$this->Sender->find('all', array(
    'joins' => array(
        array(
            'table' => 'private_messages_users',
            'alias' => 'PrivateMessagesUser',
            'type' => 'inner',
            'conditions' => array(
                'PrivateMessagesUser.sender_id = Sender.id',
                'PrivateMessagesUser.recipient_id' => 3
            )
        )
    )
));

Мой последний совет для вас - поместить этот код в модель. По возможности следуйте принципу «жирных моделей, тощих контроллеров».

В модели Sender:

function fetchByRecipientId($recipientId) {
    ...
}

Удачи!


РЕДАКТИРОВАТЬ: Для того, чтобы сделать эту работу для нумерации страниц, следуйте методам выше, но используйте следующий формат:

$this->paginate = array(
    'PrivateMessagesUser' => array(
        'conditions' => array('PrivateMessagesUser.recipient_id' => 3),
        'contain' => array('Sender'),
        // 'order' => ... other keys if you wish
    )
);
$this->set('senders', $this->paginate());
1 голос
/ 04 декабря 2010

Вы можете поместить условия внутри контейнера, например:

$this->Sender->find('all', array(
   'contain' => array(
      'PrivateMessagesUser' => array('conditions' => array('recipient_id' => 3))
   )
));

EDIT: Попробуйте изменить $this->paginate следующим образом:

$this->paginate = array(
        'conditions' => array(
            'PrivateMessage.id' => $this->__getUserPrivateMessagesInbox()//array of message id's
        ),
        'fields' => array('PrivateMessagesUser.id'),
        'contain' => array(
            'Sender' => array(
                'fields' => array('id', 'username'),
            ),
            'Recipient' => array(
                'fields' => array('id', 'username'),
                'conditions' => array('Recipient.id' => $this->Auth->user('id'))
            )
        )
    )

Тогда позвоните своему пагинату $this->paginate($this->PrivateMessage)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...