Cakephp模型协会

时间:2010-10-11 18:40:10

标签: mysql cakephp

我有以下简单模型:

  • Item belongsTo CatalogItem
  • CatalogItem hasMany Item,belongsTo Section
  • Section hasMany CatalogItem
  • 我正在尝试按照catalogitem为某个部分获取项目数量 - 相当于:

    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 :(得分:0)

    这是一个更长的方式,“蛋糕”方式:

    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);
    

    它是如何运作的:

    • 定义一个virtual field(蛋糕1.3+仅AFAIK),它将计算项目
    • 获取属于您感兴趣的部分的所有Catalogitems
    • 使用Set::extract()以简单数组获取Catalogitems
    • 使用Catalogitems数组在计算和分组时过滤项目

    注意:您似乎没有在数据库中使用Cake's naming conventions。这可能会伤害你。

    答案 1 :(得分:0)

    对不起,在我的第一个回答中,我错过了你的GROUP BY要求,这是问题的重点,我现在意识到了。我还没有用过这个,但最近我遇到过它,看起来它可能会完成你想要的东西:可链接的行为。

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

    与Containable类似,但仅适用于左右连接,可生成更紧凑的查询并支持GROUP BY。

    http://github.com/rafaelbandeira3/linkable

    答案 2 :(得分:0)

    @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