【问题标题】:Cakephp 3: Countercache with conditions on the target modelCakephp 3: Countercache 与目标模型的条件
【发布时间】:2019-05-18 21:25:17
【问题描述】:

我正在尝试计算与计划关联的 Spot 数量,但仅限于在计划续订日期之后下载的 Spot。希望这是有道理的。我会想像这样的东西,但它不起作用:

class SpotsTable extends Table
{
    public function initialize(array $config)
    {
        $this->addBehavior('CounterCache', [
            'Plan' => [
                'creditsUsed' => [
                    'conditions' => [
                        'downloaded >' => 'Plan.renewed'
                    ]
                ]
            ]
        ]);
        ...
    }
...
}

现在基本上它就像Plan.renewed 意味着NULL。 这是可能的,还是我走错了路?

【问题讨论】:

    标签: cakephp behavior cakephp-3.x counter-cache


    【解决方案1】:

    两个问题

    1。标识符不能作为字符串值传递

    当使用key => value 格式时,除非它是表达式对象,否则值端将始终受到绑定/转义/强制转换,因此由于downloaded 列可能是日期/时间类型,因此您最终会Plan.renewed 被绑定为字符串,因此最终的 SQL 将类似于:

    downloaded > 'Plan.renewed'
    

    这可能总是导致错误。长话短说,例如使用标识符表达式:

    'Spots.downloaded >' => new \Cake\Database\Expression\IdentifierExpression('Plan.renewed')
    

    2。计数器查询无权访问关联表

    Plan.renewed 在计数器缓存行为生成的查询中将不可访问,它不会自动包含/加入关联,它会根据当前处理的@987654329 中的外键值创建一个带有条件的简单查询@实体。

    因此,您必须使用自定义/修改后的查询,例如使用自定义查找器,如下所示:

    'creditsUsed' => [
        'finder' => 'downloadedAfterPlanRenewal'
    ]
    
    // in SpotsTable
    
    public function findDownloadedAfterPlanRenewal(\Cake\ORM\Query $query, array $options)
    {
        return $query
            ->innerJoinWith('Plan')
            ->where([
                'Spots.downloaded >' => $query->identifier('Plan.renewed')
            ]);
    }
    

    这将正确加入关联,以便您可以与来自Plan 的字段进行比较。该行为生成的原始主键条件将已应用于给定的查询对象。

    另见

    【讨论】:

    • 谢谢。做到了。我在想自定义查找器可能是一种方式,但我永远不会想出标识符的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2018-12-30
    相关资源
    最近更新 更多