Можно ли разбить пользовательский запрос на страницы, не переопределяя разбиение на страницы по умолчанию?

В моем приложении CakePHP (1.2) есть два действия, которые используют нумерацию страниц — индексирование и поиск.

В предыдущем вопросе я узнал, что для применения пороговой оценки к результатам поиска мне нужно использовать ключевое слово HAVING MySQL. Поскольку CakePHP не поддерживает это изначально, мне нужно перейти к пользовательскому запросу, чтобы выполнить это.

Все руководства, которые я могу найти для настраиваемого разбиения на страницы запросов, включают переопределение методов paginate() и paginateCount().

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

Есть ли способ, которым я могу (кхм) получить свой торт и съесть его тоже?


person Tom Wright    schedule 27.09.2011    source источник


Ответы (2)


На самом деле, если вы МОЖЕТЕ сделать это с помощью find, вы МОЖЕТЕ сделать это с разбиением на страницы. Вы можете посмотреть здесь

Но чтобы быть более точным, вы можете добавить условия/ограничения/поля/содержание/порядок и т. д., которые вы используете в поиске, в функцию разбиения на страницы.

Я не использую группу в разбиении на страницы, но она ДОЛЖНА работать: D

В вашем случае у вас будет что-то вроде этого:

$this->paginate = array(
   'fields' => array(
        'Product.category_id',
        'COUNT(Product.hotel_id) as total'
    ),
   'group' => array(
        'Product.category_id HAVING COUNT(Product.hotel_id) > 1')
    )
);

$data = $this->paginate('Product');

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

РЕДАКТИРОВАТЬ:

Вы можете попробовать сделать что-то вроде этого:

Переопределите paginate() и paginateCount(), но с настройкой введите условие, чтобы вы могли определить, имеет ли это разбивку на страницы с наличием или нет. Что-то вроде этого:

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()){
   //if no having conditions set return the parent paginate 
   if (empty($conditions['having'])
       return parent::paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra)
   //if having conditions set return your override

//override code here

}

Затем вы делаете что-то подобное в paginateCount(), таким образом, у вас есть выборочная разбивка на страницы. не забудьте сделать unset $conditions['having'], если он не нужен, или не забудьте поместить его куда-нибудь, что не повлияет на вашу находку;)

person api55    schedule 27.09.2011
comment
Это интересное решение, но, к сожалению, не работает paginateCount() из-за отсутствия столбца с именем score. - person Tom Wright; 27.09.2011
comment
+1 За скрытое предложение HAVING в группе по строке. Но когда вы копируете, позаботьтесь об этих отвратительных фигурных кавычках. - person Johan; 27.09.2011
comment
извините за это, спасибо за редактирование @TomWright Хммм, это правда, я полагаю, вам нужно переопределить функцию paginateCount(), прочитав немного больше пользовательского запроса в книга я вижу, что вам действительно нужно переопределить по крайней мере paginateCount(); НО вы можете сделать что-то, чтобы различать, что использовать, я объясняю это предложение внизу моего ответа. - person api55; 27.09.2011
comment
Спасибо апи55. Я отметил это как правильный, потому что это, очевидно, правильный подход, но, похоже, он вызвал странную проблему. См. мой новый вопрос: stackoverflow.com/q/7583307/50151 - person Tom Wright; 28.09.2011

На самом деле заставить это работать было больше головной боли, чем вы могли бы разумно ожидать.

Хотя я в основном следовал совету api55 (спасибо!), я также преодолел множество других препятствий:

  • Это невозможно сделать parent::paginateCount(). Я преодолел это, заменив другим ( и видимо лучше) версия в app_model.php.

  • Поскольку paginateCount() — это всего лишь оболочка для find('count'), он не принимает параметр fields. Это сложно для меня, так как я полагаюсь на это, чтобы втиснуть мой производный столбец (оценка полнотекстового поиска). Я преодолел это, передав значение fields дважды в paginate - один раз как fields и один раз как "sneaky". Cake помещает любые параметры, которые он не распознает, в массив extra.

  • Связав это вместе, у меня было переопределение paginateCount() в моей модели, которое проверяет, есть ли у extra ключ, называемый «подлым». Если это так, он выполняет find('all') и использует содержимое sneaky для заполнения полей.

В такие дни, как сегодня, я должен сделать шаг назад и вспомнить все положительные стороны использования фреймворка.

person Tom Wright    schedule 28.09.2011