在自定义查找中使用Containable

时间:2014-08-30 20:20:35

标签: cakephp-2.3

我正在使用Cakephp 2.3.x

我有一个具有以下hasMany关系的模型:

class Product extends AppModel {
    public $name = 'Product';
    public $actsAs = array('Containable');
    public $findMethods = array('instockinactive' => true);
    public $hasMany = array(
        'Listing' => array(
                'className'     => 'Listing',
                'foreignKey'    => 'product_id',
                'dependent'     =>  false,
                'order'         => 'Listing.market ASC'
        )

数据库看起来如下所示。我想选择所有产品'使用' Listing.listingstatus' ='无效'。我想我应该能够用Contain做到这一点。

array(
    (int) 0 => array(
          'Product' => array(
            'id' => '15',
            'skutype' => 'Standard',
            'sku' => 'dba:43253R',
            'mpn' => '43253R',
            'brand' => 'Hamilton Beach',
            'upc' => '040094916559',
            'isbn' => '',
            'ean' => '',
            'gtin' => '',
            'jan' => '',
            'stock' => 'Yes',
            'condition' => 'New',
            'created' => '1406243817',
            'modified' => '1406243817'
        ),
        'Listing' => array(
            (int) 0 => array(
                'id' => '32',
                'product_id' => '15',
                'market_id' => '1',
                'sku' => 'dba:43253R',
                'market' => 'jskdistributing',
                'listingstatus' => 'Active',
                'itemid' => '191260995302',
                'created' => '2014-07-24 19:24:50',
                'modified' => '2014-07-24 19:24:50'
            )
        )
    ),
    (int) 1 => array(
        'Product' => array(
            'id' => '229',
            'skutype' => 'Standard',
            'sku' => 'dba:48465',
            'mpn' => '48465',
            'brand' => 'Hamilton Beach',
            'upc' => '040094484652',
            'isbn' => '',
            'ean' => '',
            'gtin' => '',
            'jan' => '',
            'stock' => 'Yes',
            'condition' => 'New',
            'created' => '1407615778',
            'modified' => '1407615778'
        ),
        'Listing' => array(
            (int) 0 => array(
                'id' => '238',
                'product_id' => '229',
                'market_id' => '1',
                'sku' => 'dba:48465',
                'market' => 'jskdistributing',
                'listingstatus' => 'Inactive',
                'itemid' => '191280736083',
                'created' => '2014-08-09 16:33:55',
                'modified' => '2014-08-09 16:33:55'
            )
        )
    )

自定义查找如下:

protected function _findInstockinactive ($state, $query, $results = array()) {
        if ($state === 'before') {
            $query['order'] = array('Product.sku' => 'asc');
            $query['conditions'] = array('Product.stock' => 'Yes');            
            $query['contain'] = array('Listing'  => array(
                'conditions' => array('Listing.listingstatus =' => 'Inactive')
            );
            return $query;
        }        
        return $results;
    }

此查找的结果是它选择每个产品记录和每个列表记录。清单没有显示如下所示的内容。

array(     
    (int) 0 => array(
        'Product' => array(
            'id' => '15',
            'skutype' => 'Standard',
            'sku' => 'dba:43253R',
            'mpn' => '43253R',
            'brand' => 'Hamilton Beach',
            'upc' => '040094916559',
            'isbn' => '',
            'ean' => '',
            'gtin' => '',
            'jan' => '',
            'stock' => 'Yes',
            'condition' => 'New',
            'created' => '1406243817',
            'modified' => '1406243817'
        ),
        'Listing' => array()
        )
    ),
    (int) 1 => array(
        'Product' => array(
            'id' => '229',
            'skutype' => 'Standard',
            'sku' => 'dba:48465',
            'mpn' => '48465',
            'brand' => 'Hamilton Beach',
            'upc' => '040094484652',
            'isbn' => '',
            'ean' => '',
            'gtin' => '',
            'jan' => '',
            'stock' => 'Yes',
            'condition' => 'New',
            'created' => '1407615778',
            'modified' => '1407615778'
        ),
        'Listing' => array()
        )
    )

1 个答案:

答案 0 :(得分:1)

可包含行为和模型关联使用" LEFT"默认情况下加入。 如果您希望关联Model / s上的条件减少为主模型返回的行,您可以:

1)按如下方式定义关联:

public $hasMany = array(
    'Listing' => array(
            'className'     => 'Listing',
            'foreignKey'    => 'product_id',
            'dependent'     =>  false,
            'order'         => 'Listing.market ASC'
            'type'          => 'INNER'
    )

这显然适用于产品型号的所有find()。

2)将条件应用于您的自定义查找:

        $query['order'] = array('Product.sku' => 'asc');
        $query['conditions'] = array(
            'Product.stock' => 'Yes',
            'Listing.listingstatus =' => 'Inactive'
        );
        $query['contain'] = array('Listing');
        return $query;

3)使用'加入'而不是包含'在自定义查找:

        $query['order'] = array('Product.sku' => 'asc');
        $query['conditions'] = array(
            'Product.stock' => 'Yes',
            'Listing.listingstatus =' => 'Inactive'
        );
        $query['join'] = array(
            'table' => 'listings',
            'alias' => 'ListingJoin',
            'type' => 'INNER',
        );
        return $query;

只生成一个查询并且性能更好。