Поведение Разница между find('count') и find('all') cakePHP

У меня странная проблема в CakePHP, где

$this->something->find('count'); 

работает отлично, но

$this->something->find('all'); 

ничего не возвращает (даже пустой массив, какие-либо ошибки или что-то еще).

редактировать: оказывается, я получаю ошибку sql: «Ошибка SQL: 1054: неизвестный столбец» - для столбца, который действительно существует. (users.display_name в запросе sql ниже):

SELECT item.id, item.name, item.description, item.user_id, users.display_name FROM item LEFT JOIN users ON (item.user_id = users.id);

Я также пытался использовать findAllBy, а также разбиение на страницы (на самом деле разбиение на страницы - это то, что я пытаюсь сделать, хотя из того, что я собрал, разбиение на страницы и поиск («все») очень похожи по функциональности).

Странно то, что find('all') работает везде - только в этом конкретном контроллере он ведет себя странно. Я не получаю никаких ошибок, просто пустой результат.

Я думаю, что могу упустить из виду что-то довольно простое, но любая помощь приветствуется. Спасибо!


person quadium32    schedule 14.02.2012    source источник
comment
Вы пробовали смотреть на вывод SQL? Обычно это хороший показатель   -  person Barry Chapman    schedule 15.02.2012
comment
версия торта? также - что именно возвращает find(count)? целочисленное значение?   -  person mark    schedule 15.02.2012
comment
var_dump($this->something->find('all')); сообщит вам точно, что он возвращает.   -  person Xeoncross    schedule 15.02.2012
comment
То есть у вас вообще нет выхода? Похоже на черную дыру или нехватку памяти...   -  person Barry Chapman    schedule 15.02.2012
comment
@BarryChapman: вывод SQL говорит об ошибке SQL: 1054: неизвестный столбец (для существующего столбца - так что, возможно, это проблема в модели?)   -  person quadium32    schedule 15.02.2012
comment
@mark: версия cakephp — 1.3.1, а find(count) возвращает целое число (правильное) Xeoncross: var_dump показывает его как логическое (false)   -  person quadium32    schedule 15.02.2012
comment
а какой правильный? 0 или значение больше нуля? но похоже, что ваши объединения неправильно настроены для поиска (все). поэтому он может присоединиться к неизвестным таблицам. почему вы не отображаете точный запрос торта и точный запрос sql, созданный в вашем вопросе? никто не может помочь вам таким образом.   -  person mark    schedule 15.02.2012
comment
больше нуля - примерно 450, столько же, сколько и общее количество строк, которые должны быть возвращены при поиске (все).   -  person quadium32    schedule 15.02.2012
comment
Я отредактировал, чтобы добавить результат SQL. Он использует объединение, хотя, кажется, это отлично работает в других контроллерах (из того, что я видел до сих пор).   -  person quadium32    schedule 15.02.2012
comment
У вас случайно не было бы виртуального поля, вашей модели чего-то, не так ли?   -  person Francois Deschenes    schedule 15.02.2012
comment
@FrancoisDeschenes: На самом деле знаю - users.display_name - это виртуальное поле, которое объединяет имя и фамилию и помогает форматировать.   -  person quadium32    schedule 15.02.2012
comment
Тогда это, наверное, твоя проблема. Очевидно, что в этом запросе он не обрабатывается должным образом. Виртуальные поля иногда могут быть немного сложными. Попробуйте временно удалить его и посмотреть, решит ли это вашу проблему. Если это решит вашу проблему, дайте мне знать, и я отправлю ответ ниже с более подробной информацией.   -  person Francois Deschenes    schedule 15.02.2012
comment
@FrancoisDeschenes да, это работает отлично. Интересный..   -  person quadium32    schedule 15.02.2012


Ответы (2)


Итак, согласно нашему обсуждению, проблема, с которой вы столкнулись, связана с виртуальными полями. Ознакомьтесь с документацией, а точнее с виртуальные поля и псевдонимы моделей и ограничение виртуальных полей разделы.

Из вашего описания выше, похоже, что у вас есть соединение, указанное в вашем виртуальном поле, которое может вызвать ошибку, которую вы видите, потому что оно добавит JOIN перед FROM. Если вы настаиваете на использовании виртуального поля, я предлагаю вам переписать его, чтобы использовать подзапрос. Убедитесь, что ваш подзапрос возвращает только 1 столбец.

Пример: (http://web-development-blog.co.uk/2011/03/08/cakephp-virtual-field-count-another-modeltable/)

public $virtualFields = array(
    'count' => 'SELECT COUNT(*) FROM stacks Stack'
);

Кроме того, вы можете использовать Model::beforeFind для привязки необходимых моделей (при необходимости) и изменить параметры запроса.

Если вы не можете понять это, пожалуйста, напишите свою модель, и я вам помогу.

person Francois Deschenes    schedule 15.02.2012
comment
это заставило меня двигаться в правильном направлении. Спасибо за вашу помощь! - person quadium32; 15.02.2012

Конкретная проблема, связанная с разницей в поведении, заключается в том, что find('count') будет выполнять базовый COUNT(*) запрос к вашей базе данных, чтобы определить количество строк.

find('all'), однако, выполняет другой запрос, и если предоставленный вами SQL-код — это то, что он пытается использовать, он недействителен:

SELECT item.id, item.name, item.description, item.user_id, users.display_name LEFT JOIN users ON (item.user_id = users.id);

Там нет декларации FROM (от чего именно SELECT?), и если вы не настроили свои модели Item, User или App (может быть, настроив $useTable = false?), вы имеете дело с необычной ошибкой.

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

person mrlee    schedule 15.02.2012
comment
ах, вот что я получаю за то, что не копирую и не вставляю. На самом деле в нем есть оператор FROM (я только что отредактировал основной пост, чтобы отразить это). Тем не менее, это определенно хорошая идея, чтобы проверить различия для каждого контроллера - я проверю каждый из них, которые используют эту конкретную модель. - person quadium32; 15.02.2012