在包含的模型上使用limit()

时间:2015-04-21 14:53:48

标签: cakephp orm cakephp-3.0

代码

假设我有两个名为ProductImage的模型,它们由Product hasMany ImageImage belongsTo Product链接。

现在,我想要获取所有带有第一张图片的产品。我会使用这段代码:

$this->Products->find('all')
    ->contain([
        'Images' => function($q) {
            return $q
                ->order('created ASC')
                ->limit(1);
        }
    ]);

看起来对,对吗?除非现在只有一个的产品包含图像,但实际上每个产品至少包含一个图像(如果没有限制则查询)。

生成的查询

问题似乎是限制,因为这会产生以下两个查询(例如):

SELECT
    Products.id AS `Products__id`,
FROM
    products Products

SELECT
    Images.id AS `Images__id`,
    Images.product_id AS `Images__product_id`,
    Images.created AS `Images__created`
FROM
    images Images
WHERE
    Images.product_id in (1,2,3,4,5)
ORDER BY
    created ASC
LIMIT 1

查看第二个查询,很明显这将永远只会产生一个图像。

问题

但是,当我拨打limit(1)时,我原本期望Cake ORM将图片限制为每个产品

我的问题:这是我使用ORM的错误吗?如果是这样,应该我如何将图片数量限制为每个图片一个

3 个答案:

答案 0 :(得分:14)

最简洁的方法是创建另一个关联:

$this->hasOne('FirstImage', [
    'className' => 'Images',
    'foreignKey' => 'image_id',
    'strategy' => 'select',
    'sort' => ['FirstImage.created' => 'DESC'],
    'conditions' => function ($e, $query) {
        $query->limit(1);
        return [];
    }
])

答案 1 :(得分:4)

检查一下,这是我的代码

 $this->Orders->hasOne('Collections', [
                    'className' => 'Collections',
                    'foreignKey' => 'order_id',
                    'strategy' => 'select',
                    'conditions' => function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) {
                    $query->order(['Collections.id' => 'ASC']);
                    return [];
                                                                                                                         }
                    ]);


                    $Lists = $this->Orders->find('all')->where($condition)->contain(['Collections'])->order(['Orders.due_date DESC']);
                    $this->set(compact('Lists'));

答案 2 :(得分:0)

如果您将其限制为一张图像的原因是您希望拥有默认图像。您可以考虑在图像表中添加default字段并执行如下的别名:

var $hasOne = array(
    'CoverImage' => array(
        'className' => 'Image',
        'conditions' => array('CoverImage.default' => true),
    ),

看起来你正在使用Cake v3,所以你可以添加等效关联,因为上面是2.x样本。