мы часто имеем дело с кодом, который выглядит следующим образом:Каким образом можно правильно встраивать пользовательские поля в запрос поиска CakePHP?
return $this->find(
'all', [
'fields' => ['DISTINCT Tag.tag', 'COUNT(Tag.tag) as count'],
'group' => ['Tag.tag'],
'order' => ['count' => 'DESC']
]);
Этот запрос приводит нас к следующему выходу:
[0] => Array
(
[Tag] => Array
(
[tag] => walls.io
)
[0] => Array
(
[count] => 15
)
)
Как вы можете видеть, этот запрос возвращает результаты в «как-то не так». Поле «count», к сожалению, помещается в псевдо-[0] -аррей.
IIRC, CakePHP использует внутренний синтаксис, например Tag__field, для правильного вложения виртуальных полей.
При изменении кода в модели __- синтаксиса, проблема остается той же:
return $this->find(
'all', [
'fields' => ['DISTINCT Tag.tag', 'COUNT(Tag.tag) as Tag__count'],
'group' => ['Tag.tag'],
'order' => ['COUNT(Tag.tag)' => 'DESC']
]);
Выход:
[0] => Array
(
[Tag] => Array
(
[tag] => walls.io
)
[0] => Array
(
[Tag__count] => 15
)
)
Обход 1: array_map
CakePHP плюсы: Есть там лучшее/более элегантное решение, чем ручное сопоставление массива после оператора select?
$tags = array_map(function($tag) {
$tag['Tag']['count'] = $tag[0]['count'];
unset($tag[0]);
return $tag;
}, $tags);
Обход 2: виртуальное поле
Как описано выше, использование виртуального поля может решить эту проблему:
$this->virtualFields = ['count' => 'COUNT(Tag.Tag)'];
return $this->find(
'all', [
'group' => ['Tag.tag'],
'order' => [$this->getVirtualField('count') => 'DESC']
]);
К сожалению, с этим решением, это не представляется возможным укажите ЛЮБЫЕ поля. только полностью покидая «поля» -key, вложение массива работает так, как ожидалось. при выборе $ fields = ['Tag.tag', $ this-> getVirtualField ('count')] повторное вложение неверно.
CakePHP pros: Знаете ли вы метод, в котором вложенность выполняется правильно, даже если вы указываете свои собственные поля?
Я пробовал все, что вы упоминали ... И никто из них не работает ... Я снова посмотрю. – Anubhav