Сортировка страниц CakePHP по вычисляемому полю (COUNT)
у меня была проблема с сортировкой списка страниц при использовании вычисляемого поля, такого как COUNT() в cakephp 1.3
предположим, что у меня есть две модели: статья и комментарии (1 статья x N комментариев), и я хочу отобразить разбитый на страницы список статей, включая количество комментариев для каждого из них. У меня было бы что-то вроде этого:
:
$this->paginate = array('limit'=>80,
'recursive'=>-1,
'fields'=>array("Article.*","COUNT(Comment.id) as nbr_comments"),
'joins'=>array(array( 'table' => 'comments',
'alias' => 'Comment',
'type' => 'LEFT',
'conditions' => array('Comment.article_id = Article.id'))
),
'group'=>"Article.id"
);
(мне пришлось заменить findCount()
метод для разбиения на страницы с помощью группы by)
проблема в том, что в представлении,sort()
метод не сработает:
<th><?php echo $this->Paginator->sort('nbr_comments');?></th> //life is not that easy
я смог создать обходной путь, "обманув" разбиение на страницы и сортировку:
контроллер
$order = "Article.title";
$direction = "asc";
if(isset($this->passedArgs['sort']) && $this->passedArgs['sort']=="nbr_comments")
$order = $this->passedArgs['sort'];
$direction = $this->passedArgs['direction'];
unset($this->passedArgs['sort']);
unset($this->passedArgs['direction']);
}
$this->paginate = array(... 'order'=>$order." ".$direction, ...);
$this->set('articles', $this->paginate());
if($order == "clicks"){
$this->passedArgs['sort'] = $order;
$this->passedArgs['direction'] = $direction;
}
посмотреть
<?php $direction = (isset($this->passedArgs['direction']) && isset($this->passedArgs['sort']) && $this->passedArgs['sort'] == "nbr_comments" && $this->passedArgs['direction'] == "desc")?"asc":"desc";?>
<th><?php echo $this->Paginator->sort('Hits','clicks',array('direction'=>$direction));?></th>
и это работает.. но кажется, что это слишком много кода для чего-то, что должно быть прозрачным для разработчика. (Такое чувство, что я делаю работу торта) так что я спрашиваю, есть ли еще что-нибудь попроще. путь. Может быть, у торта есть эта функция, но он решил ее скрыть.. О_о.. в документации нет ничего об этом, и я не нашел другого хорошего решения на S. O... как вы это делаете?
спасибо заранее!
2 ответов
может быть, ваша проблема может быть решена с помощью виртуальные поля ?
Если вы создадите настраиваемое поле для вашего вычисляемого поля, вы сможете сортировать с помощью метода Paginator->sort() в этом настраиваемом поле.
Я нашел это решение здесь в комментариях (нет необходимости настраивать метод paginate и т. д. использование пользовательских полей вместо исходного решения adnan).
то, что вы можете сделать, это использовать торт counterCache функциональность в определении модели. Вместо того, чтобы вычислять количество комментариев во время чтения, вы добавляете nbr_comments
как поле int в вашем articles
таблица. Каждый раз, когда Comment
вставляется или удаляется, nbr_comments
будет автоматически обновляться.
в своем Comment
модель:
var $belongsTo = array(
'Article' => array(
'counterCache' => 'nbr_comments'
)
);
теперь вы можете просто использовать $this->Paginator->sort('Article.nbr_comments');
вам не нужно делать ничего фанки в вашем контроллере.