Cakephp分页按计算字段排序(COUNT)

时间:2011-05-16 13:35:09

标签: sorting cakephp count pagination aggregate-functions

在cakephp 1.3中使用计算字段(例如COUNT()时,我在排序分页列表时遇到问题

假设我有两个模型:文章和评论(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()方法,以便使用group 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>

它的工作原理......但是对于那些应该对开发者来说透明的东西来说似乎代码太多了。 (感觉我正在做蛋糕的工作)所以我问是否还有另一种更简单的方法。也许蛋糕有这个功能,但决定隐藏它.. o_O ..在文档上没有关于这个,我还没有找到另一个关于S.O的好解决方案......你是怎么做到的?

提前致谢!

2 个答案:

答案 0 :(得分:6)

也许您的问题可以使用Virtual fields来解决?

如果为计算字段创建自定义字段,则可以使用该自定义字段上的Paginator-&gt; sort()方法进行排序。

我在评论中找到了解决方案there(不需要使用自定义字段而不是adnan的初始解决方案来自定义分页方法等。)

答案 1 :(得分:2)

您可能想要做的是在模型定义中使用Cake的counterCache功能。您可以在nbr_comments表中将articles添加为int字段,而不是在读取时计算注释计数。每次插入或删除Comment时,nbr_comments都会自动更新。

Comment模型中:

var $belongsTo = array(
    'Article' => array(
        'counterCache' => 'nbr_comments'
    )
);

现在你可以使用$this->Paginator->sort('Article.nbr_comments');你不需要在控制器中做任何有趣的事情。