Я довольно долго пытался использовать Containable Behavior в CakePHP, но не могу заставить его работать так, как ожидал.
Мое приложение отличается, но для упрощения я приведу этот пример. Допустим, у меня есть форум с темами и действиями, и действия могут быть оценены. Общие отношения будут:
Форум: hasMany [Тема]
Тема: ownTo [Форум], hasMany [Активность]
Активность: ownTo [Тема], hasMany [Рейтинг]
Рейтинг: принадлежит [Активность]
Чего я хочу добиться, так это с помощью метода поиска получить все оценки, выполненные на определенном форуме. То, что я должен сделать, должно быть следующим:
$this->Rating->find('count', array(
'contain' => array(
'Activity' => array(
'Thread'
)
),
'conditions' => array(
'Thread.forum_id' => 1
)
));
Но результат запроса:
SELECT COUNT(*) AS `count` FROM `ratings` AS `Rating` LEFT JOIN `activities` AS `Activity` ON (`Rating`.`activity_id` = `Activity`.`id`) WHERE `Thread`.`forum_id` = 1;
Я выполнил это с помощью опции 'joins', но она более сложная, и мне приходится использовать это своего рода действие во многих ситуациях.
Все файлы, связанные с примером, можно найти здесь: http://dl.dropbox.com/u/3285746/StackOverflow-ContainableBehavior.rar
Спасибо
Обновление 23/11/2011
После изучения структуры и благодаря ответам Moz Morris и api55 я нашел источник проблемы.
Основная проблема заключалась в том, что, как я понял CakePHP, я думал, что он каждый раз запрашивает использование соединений. То, что он этого не делает, реальная операция, которую он будет выполнять для получения результата, который я искал, будет выглядеть примерно так:
SELECT * FROM Rating JOIN Activity...
SELECT * FROM Activity JOIN Thread...
SELECT * FROM Activity JOIN Thread...
...
Это означает, что он будет выполнять запрос для получения всех действий, а затем для каждого действия выполнять запрос для получения потоков ... Мой подход был неудачным не из-за неправильного использования контейнерного поведения, а потому Параметр условий был применен ко всем запросам, и на первом из них произошел сбой из-за отсутствия таблицы потоков. После выяснения этого, есть два возможных решения:
Как и сказал api55, используя условия внутри массива «Содержать», он будет применять их только к запросам, использующим таблицу Thread. Но при этом проблема остается, потому что у нас слишком много запросов.
Как сказал Моз Моррис, связывание модели потоков с рейтингом также будет работать, и она будет выполнять один запрос, чего мы и хотим. Проблема в том, что я вижу это как патч, который пропускает отношения между моделями и не следует философии CakePHP.
Я отметил правильное решение api55, поскольку оно решает конкретную проблему, с которой я столкнулся, но оба дают решение проблемы.