Intereting Posts
MySQL: как получить разницу между двумя метками времени в секундах Можно ли использовать WordPress API для создания сообщений на wordpress.com? Поля списка CodeIgniter Является ли CGI все еще медленным при использовании с компилируемой программой, которая не требует виртуальной машины? Проверьте, является ли строка временной отметкой unix формат JSON с помощью функции php и результата печати внутри идентификатора div # Как архивировать динамический (PHP) сайт как статический HTML? Получение удаленной адресной информации PHP по URL-адресу Самый простой способ класса «Текущая страница» nav? Каков правильный способ реализации заводского шаблона? Итерации через определенное дерево каталогов и сохранение всех .ttf-файлов в массив в PHP ImageMagick: как рисовать две строки с разным размером над изображением? Обрезка блока текста до ближайшего слова, когда достигается определенный предел символов? Синтаксис / оператор массива PHP? Неверная ошибка символа PHP

Ошибка ограничения модели CakePHP и HABTM

У меня есть серия моделей Post, в которых есть модели AndEndBelongsToMany Media. В некоторых вызовах функций внутри модели Post мне не нужно извлекать весь список моделей мультимедиа. Однако, когда я использую следующий код:

$this->unbindModel( array('hasAndBelongsToMany' => array('Media')) ); // Rebind to get only the fields we need: $this->bindModel( array('hasAndBelongsToMany' => array( 'Media' => array( 'className' => 'Media', 'joinTable' => 'media_posts', 'foreignKey' => 'post_id', 'associationForeignKey' => 'media_id', 'limit' => 1, 'fields' => array('Media.type', 'Media.path', 'Media.title') ) ) ) ); $this->find('all', $params); 

Этот предел работает только на одной из первой модели Post Post, и все следующие модели Post не имеют связанных носителей:

 Array ( [0] => Array ( [Profile] => Array ( ) [Media] => Array ( [0] => Array ( [type] => photo [path] => '' [title] => '' ) ) ) [1] => Array ( [Profile] => Array ( ) [Media] => Array ( ) ) ) 

Любые предложения были бы замечательными. Благодаря!

почему бы не использовать сдерживаемое поведение

 // you would probably want the next line in the app_model ot be able to use it with all models $this->Post->actsAs = array('Containable') $params['conditions'] = array( ); $params['contain'] = array( 'Media' => array( 'fields' => array( 'type', 'path', 'title' ), 'limit' => 1 ) ); $this->Post->find('all', $params); 

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

Просто попробовал это и получил этот sql (Module <-> Tag):

 SELECT `Module`.`id` FROM `modules` AS `Module` WHERE 1 = 1 

а также

 SELECT `Tag`.`id`, `ModulesTag`.`module_id`, `ModulesTag`.`tag_id` FROM `tags` AS `Tag` JOIN `modules_tags` AS `ModulesTag` ON (`ModulesTag`.`module_id` IN (1, 2, 3, 4) AND `ModulesTag`.`tag_id` = `Tag`.`id`) WHERE `Tag`.`belongs_to` = 'Module' ORDER BY `Tag`.`name` ASC LIMIT 1 

очевидно, что не может вернуть желаемый результат, так как вам придется делать запрос для каждого результата модуля (что опять-таки приведет к слишком большому числу запросов).

В качестве вывода я бы вернул все теги (в моем примере), поскольку накладные расходы в слишком большом количестве строк результатов лучше, чем накладные расходы слишком большого количества запросов.

Cake извлекает все связанные с Habtm записи в одном пакетном запросе, а затем собирает их в массив результатов впоследствии. Любые дополнительные условия, которые вы укажете в ассоциации, будут использоваться как в запросе, так что это будет выглядеть примерно так:

 SELECT … FROM Media WHERE Media.id in (1, 2, 3, …) LIMIT 1 

Таким образом, он будет извлекать только одну модель HABTM.

Для этого нет простого решения. Возможно, вы могли бы снова подумать об исходной предпосылке и почему первая запись ( LIMIT 1 ), предположительно, правильная, возможно, вы можете найти другое условие для запроса.

В противном случае вы можете перестроить свои модели, чтобы Media hasMany отношение medias_posts к medias_posts , сводной таблице. Для hasMany и принадлежит к запросам, Cake автоматически выполняет JOIN запросы. Тогда вы можете использовать предложение GROUP BY , которое даст вам желаемый результат:

 SELECT … FROM Media JOIN medias_posts … GROUP BY medias_posts.post_id 

Возможно, вам также захочется поэкспериментировать с передачей параметра 'join' с запросом, чтобы добиться этого эффекта без обширного перепроверки.

 $this->Media->find('all', array('join' => array(…), …)); 

Попробуй это:

 $this->yourModel->hasAndBelongsToMany['Media'] = false; // or null 

А затем установите свою ассоциацию HABTM вручную

 $this->yourModel->hasAndBelongsToMany['Media'] = array(........); 

Или просто измените ассоциацию, не опуская ее:

 $this->yourModel->HABTM['Media']['fields'] = array(....) 

CakePHP имеет очень мощный инструмент для этого сдерживаемого поведения