Cakephp 3: Countercache с условиями на целевой модели - PullRequest
0 голосов
/ 18 декабря 2018

Я пытаюсь подсчитать количество точек, связанных с планом, но ограничено точками, загруженными после даты обновления плана.Надеюсь, что это имеет смысл.Я хотел бы изобразить что-то вроде этого, но это не работает:

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

По сути, сейчас он действует так, как будто Plan.renewed означает NULL.Это возможно, или я не на том пути?

1 Ответ

0 голосов
/ 18 декабря 2018

Две проблемы

1.Идентификаторы не могут быть переданы в виде строковых значений

При использовании формата key => value сторона значений всегда будет подвергаться привязке / экранированию / приведению, если только это не объект выражения, поэтому столбец downloaded, вероятно, являетсятип даты / времени, в итоге Plan.renewed будет связан как строка, поэтому окончательный SQL будет выглядеть примерно так:

downloaded > 'Plan.renewed'

, что, вероятно, всегда приводит к значению false.Короче говоря, используйте, например, выражение-идентификатор:

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

2.Счетчик запроса не имеет доступа к связанной таблице

Plan.renewed не будет доступен в запросе, созданном поведением кэша счетчика, он не будет автоматически содержать / объединять ассоциации, он создаст простой запросс условием, основанным на значении внешнего ключа в текущей обработанной сущности Spot.

Таким образом, вы должны использовать настраиваемый / измененный запрос, например, с помощью специального поиска, что-то вроде этого:

'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.Исходные условия первичного ключа, сгенерированные поведением, уже будут применены к данному объекту запроса.

См. Также

...