在包含的模型上使用 limit()
Using limit() on contained model
代码
假设我有两个模型,名为 Product
和 Image
,它们由 Product hasMany Image
和 Image 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 将图像限制为每个产品 1 个
我的问题:这是我使用 ORM 的方式的错误吗?如果是这样,我应该如何 将图片数量限制为每张图片一张?
如果您将其限制为一张图片的原因是您想要一张默认图片。您可以考虑在图像 table 中添加一个 default
字段并像这样做一个别名:
var $hasOne = array(
'CoverImage' => array(
'className' => 'Image',
'conditions' => array('CoverImage.default' => true),
),
看起来您使用的是 Cake v3,因此您可以添加等效关联,因为上面是 2.x 示例。
最简洁的方法是创建另一个关联:
$this->hasOne('FirstImage', [
'className' => 'Images',
'foreignKey' => 'image_id',
'strategy' => 'select',
'sort' => ['FirstImage.created' => 'DESC'],
'conditions' => function ($e, $query) {
$query->limit(1);
return [];
}
])
检查一下,这是我的代码
$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'));
在模型定义中,我们将执行以下操作:
public $hasMany = [
'ModelName' => [
'limit' => 1,
'order' => 'ModelName.field DESC'
],
];
如文档中所述:https://book.cakephp.org/2/en/models/associations-linking-models-together.html#hasmany
代码
假设我有两个模型,名为 Product
和 Image
,它们由 Product hasMany Image
和 Image 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)
.
我的问题:这是我使用 ORM 的方式的错误吗?如果是这样,我应该如何 将图片数量限制为每张图片一张?
如果您将其限制为一张图片的原因是您想要一张默认图片。您可以考虑在图像 table 中添加一个 default
字段并像这样做一个别名:
var $hasOne = array(
'CoverImage' => array(
'className' => 'Image',
'conditions' => array('CoverImage.default' => true),
),
看起来您使用的是 Cake v3,因此您可以添加等效关联,因为上面是 2.x 示例。
最简洁的方法是创建另一个关联:
$this->hasOne('FirstImage', [
'className' => 'Images',
'foreignKey' => 'image_id',
'strategy' => 'select',
'sort' => ['FirstImage.created' => 'DESC'],
'conditions' => function ($e, $query) {
$query->limit(1);
return [];
}
])
检查一下,这是我的代码
$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'));
在模型定义中,我们将执行以下操作:
public $hasMany = [
'ModelName' => [
'limit' => 1,
'order' => 'ModelName.field DESC'
],
];
如文档中所述:https://book.cakephp.org/2/en/models/associations-linking-models-together.html#hasmany