Ассоциация модели Cakephp - PullRequest
       2

Ассоциация модели Cakephp

0 голосов
/ 11 октября 2010

У меня есть следующая простая модель:

Элемент принадлежит к CatalogItem CatalogItem имеет много предметов и принадлежит к разделу Раздел имеет много каталоговItem

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

SELECT catalogitem.id, count(*) FROM section LEFT JOIN catalogitem ON section.id=catalogitem.section_id LEFT JOIN item ON item.catalogitem_id=catalogitem.id WHERE section.id=5 GROUP BY catalogitem.id

Так просто в SQL, но я не могу 'заставить его работать с моделями тортов.Кто-нибудь может указать, как это сделать с моделями тортов, используя модель-> найти?Я не могу заставить его правильно сгруппировать или объединить по 3 таблицам: (

Редактировать: очень предпочитаю получать информацию в одном запросе

Ответы [ 3 ]

0 голосов
/ 12 октября 2010

Извините, в своем первом ответе я каким-то образом пропустил ваше требование GROUP BY, и теперь я понимаю, что в этом весь вопрос. Я еще не использовал это, но недавно я столкнулся с этим, и похоже, что он может выполнить то, что вы ищете: Linkable Behavior.

http://planetcakephp.org/aggregator/items/891-linkable-behavior-taking-it-easy-in-your-db

Как и Containable, но работает только с правым и левым объединениями, производит гораздо более компактные запросы и поддерживает GROUP BY.

http://github.com/rafaelbandeira3/linkable

0 голосов
/ 12 октября 2010

@ azv

Будет ли это работать для вас:

$section_id = 5;
$fields     = array('CatalogItem.id as CatalogItemId', 'count(*) AS SectionCount');
$conditions = array('Section.id' => $section_id);
$joins      = array(
    array('table' => 'catalogitem',
          'alias' => 'CatalogItem',
          'type' => 'LEFT',
          'conditions' => array('Section.id' => 'CatalogItem.section_id')
    ),
    array('table' => 'item',
          'alias' => 'Item',
          'type' => 'LEFT',
          'conditions' => array('Item.catalogitem_id' => 'CatalogItem.id')
));

$data = $this->Section->find('all',
                  array('fields' => $fields,
                        'conditions' => $conditions,
                        'joins' => $joins,
                        'group' => 'CatalogItem.id',
                        'recursive' => -1)
         );

// access your data values
foreach ($data['Section'] as $i => $datarow) {
    $catalogitem_id = $datarow['CatalogItemId'];
    $section_count  = $datarow['SectionCount'];
}

Таким образом, вы явно устанавливаете свои объединения и делаете все это в одном запросе.Смотрите здесь для получения дополнительной информации о соединениях в Cake:

http://book.cakephp.org/view/1047/Joining-tables

Надеюсь, это поможет.Всего наилучшего,
-s_r

0 голосов
/ 12 октября 2010

Вот более длинный путь, "тортовый" способ:

class Item extends AppModel
{
    /* snip */
    var $virtualFields = array('item_count' => 'count(Item.id)');

    function getCountForSection($sectionId)
    {
        $ca = $this->Catalogitem->find
            (
                'all',
                array
                (
                    'fields' => array('Catalogitem.id'),
                    'conditions' => array('Catalogitem.section_id' => $sectionId),
                    'recursive' => -1
                )
            );

        $ca = Set::extract('/Catalogitem/id', $ca);

        $ret = $this->find
            (
                'all',
                array
                (
                    'fields' => array('Item.catalogitem_id', 'item_count'),
                    'conditions' => array('Item.catalogitem_id' => $ca),
                    'group' => array('Item.catalogitem_id'),
                    'recursive' => -1
                )
            );

        return $ret;
    }
}

Тогда просто используйте его в вашем контроллере:

$ret = $this->Item->getCountForSection(1);
debug($ret);

Как это работает:

  • Определите виртуальное поле (только для торта 1.3+ AFAIK), которое будет подсчитывать предметы
  • Получить все каталоги, принадлежащие интересующему вас разделу
  • Используйте Set :: extract () , чтобы получить каталогизированные элементы в простом массиве
  • Использование массива Каталогизированных элементов для фильтрации элементов при подсчете и группировке

NB. Похоже, вы не используете Соглашения о присвоении имен Cake в вашей базе данных. Это может повредить вам.

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