Этот пост устарел! Читайте по ссылке исправленную и сильно переработанную версию!
This is totally outdated article! Follow the link to see a more complete version! Sorry. The newwer post in russian too.
Как уже писал, Containable behaivior, который отлично справляется с задачей выборки только нужных для данного действия (action). И при небольшой модификации отлично работает с методом pagination. Однако есть одна неприятная вещь, опять же связанная с тем, что pagination вызывает последовательно 2 метода модели — сначала для подсчета количества записей, а потом для выборки.
При попытке подсчитать количество записей у модели с большим количеством связей, paginator делает SQL запрос SELECT COUNT(*) со всеми положенными JOIN'ами, что при больших объемах данных существенно увеличивает время выполнения запроса. Особенно, если при этом еще и сортировку делать надо. Этот факт сильно раздражает, если в итоге нужно всего-лишь количество записей в основной модели.
Выход есть. Разглядывая код метода paginate, обнаружил, что Cake пытается сначала вызвать метод paginateCount, а если его нет, то вызывает findCount.
Ура! Определяем в модели метод paginateCount:
function paginateCount($conditions, $recursive)
{
return $this->findCount($conditions, -1);
}
и готово!
Теперь paginate считает записи только в нужной нам модели, не вызывая JOIN'ов, а возвращает записи со всеми нужными дополнительными данными.