【问题标题】:Using limit() on contained model在包含的模型上使用 limit()
【发布时间】:2015-04-21 14:53:48
【问题描述】:

代码

假设我有两个模型,名为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 将图像限制为 每个产品 1 个。

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

【问题讨论】:

  • 供将来参考:我最终只是省略了limit(),只使用数组中的第一个图像。所有答案在工作时似乎都是一种解决方法。 Cake ORM 总是对包含使用单个查询,即使这是不希望的(例如向查询添加限制时)。

标签: cakephp orm cakephp-3.0


【解决方案1】:

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

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

【讨论】:

  • 但是我没有得到最后一行,我得到了第一行。你能建议更多吗?
  • 谢谢你,我明白了。它真的有效。我想给你投票。
  • @sradha - 你是怎么解决这个问题的?我无法在主 hasOne 数组中排序,并且 order 在条件查询中也不起作用。我似乎只能得到第一个结果。
  • @MiDri 检查我已经发布了代码,它可能对你有帮助。
【解决方案2】:

检查一下,这是我的代码

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

【讨论】:

    【解决方案3】:

    如果您将其限制为一个图像的原因是您想要一个默认图像。您可能会考虑在图像表中添加一个default 字段并执行这样的别名:

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

    看起来您使用的是 Cake v3,因此您可以添加等效关联,因为上面是 2.x 示例。

    【讨论】:

      【解决方案4】:

      在模型定义中,我们将执行以下操作:

      public $hasMany = [
          'ModelName' => [
              'limit' => 1,
              'order' => 'ModelName.field DESC'
          ],
      ];
      

      如文档中所述:https://book.cakephp.org/2/en/models/associations-linking-models-together.html#hasmany

      【讨论】:

        猜你喜欢
        • 2016-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多