Как я могу написать сложный запрос поиска в CakePHP без использования `$ this-> Model-> query ()`? - PullRequest
0 голосов
/ 13 октября 2008

Привет всем, я надеюсь, что у кого-то достаточно опыта работы с Cake PHP, чтобы сделать эту работу.

Я работаю над тем, что в данный момент можно ласково назвать твиттер-клоном. По сути, у меня есть такая установка.

У пользователей много друзей. Это отношение многих ко многим к пользовательской таблице. Он хранится в таблице ссылок с именем friends_users с колонками user_id, friend_id. Users - это таблица со столбцом user_id.

Тогда у меня есть таблица с названием tips, которая ассоциируется с пользователем. Пользователь может иметь много советов.

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

Этот SQL-запрос работает отлично -

SELECT *
FROM `tips`
JOIN users ON users.id = tips.user_id
JOIN friends_users ON tips.user_id = friends_users.friend_id
WHERE (friends_users.user_id =2 or tips.user_id=2)
LIMIT 0 , 30

Возвращает советы пользователя # 2s, а также советы всех, кто является другом пользователя 2.

Теперь, как я могу сделать то же самое, используя $this->Tip->findxxxxx(user_id)

Я знаю, что могу использовать Tip->query, если понадобится, но я пытаюсь научиться трудным путем.

Ответы [ 3 ]

3 голосов
/ 13 октября 2008

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

function findTipsByUserAndFriends($userId) {
  //FriendsUser is automagically created by CakePHP "with" association
  $conditions = array('FriendsUser.user_id'=>$userId);
  $fields = 'FriendsUser.friend_id';
  //get a list friend ids for the given user
  $friendIds = $this->Tip->User->FriendsUser->find('list', compact('conditions', 'fields'));
  //get list of all userIds for whom you want the tips
  $userIds = array($userId) + $friendIds;
  $conditions = array('Tip.user_id'=>$userIds);
  $tips = $this->Tip->find('all', compact('conditions'));
  return $tips;
}

Обратите внимание, что вы вызываете первую находку в автоматически созданной модели FriendsUser, которую CakePHP использует для моделирования вашей таблицы HABTM friends_users, поэтому вам не нужно ее создавать.

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

1 голос
/ 15 июля 2011

Я бы порекомендовал вам использовать сдерживаемый, он прекрасно работает.

$aCond = array(
            'fields' => array(
                'Discount.*'
            ),
            'contain' => array(
                'Event' => array(
                    'conditions' => array('Event.id' => $iEventId)
                )
            )
        );
$aBulkDiscounts = $this->Discount->find('first', $aCond);

надеюсь, это поможет.

0 голосов
/ 13 октября 2008

В CakePHP говорят, что многим для многих является "Имеет и принадлежит многим" (HABTM). Если вы правильно настроили отношения, то вам нужно сделать двухуровневую рекурсивную находку, чтобы друг, которого вы нашли, извлекал всех своих друзей, и эти друзья загружали свои советы. Возможно, вам придется динамически связывать / отменять привязку моделей, чтобы эти друзья не могли получить своих друзей (хотя на практике это не составляет особой проблемы).

Необходимо ввести ручную запись для ассоциаций .

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