Cakephp Pagination从模型中排序数据

时间:2009-10-23 03:58:59

标签: mysql cakephp sorting pagination

我目前有一个查询会产生以下记录集:

Array ( [Contestant] => Array ( [id] => 1 [name] => test [age] => [city] => atest [telephone] => [email] => test@test.com [why_model_house] => a [highschool] => [photo] => 5329_119145013633_512383633_2487923_7196193_n0.jpg [active] => 1 ) [0] => Array ( [Contestant_votes] => 4 ) [Vote] => Array ( [id] => 1 ) )

我可以使用paginator->排序来处理其中的每个数据,除了“Contestant_votes”,因为它不属于当前在Array [0]

中的模型

我试过这样做:

        <th><?php echo $paginator->sort('Votes', '0.Contestant_votes'); ?></th> 

和此:

        <th><?php echo $paginator->sort('Votes', 'Contestant_votes'); ?></th> 

但它不起作用。 conestants_votes字段由以下查询生成:

'Contestant.*, count(Vote.contestant_id) as Contestant_votes'

这就是为什么它不在模型中。 有没有办法欺骗cakephp认为Contestant_votes是参赛者模型的一部分,或者是一种将它添加到分页器的方法,以便我可以对它进行排序?

提前致谢,

Fabian Brenes

4 个答案:

答案 0 :(得分:1)

这正是CakePHP 1.3 virtual fields的用途。

在您的情况下,请在Vote模型中添加以下内容:

var $virtualFields = array(
    'Contestant_votes' => 'COUNT(Vote.contestant_id)'
);

请注意 - 如果您向查询添加分组,此虚拟字段的行为将会更改。

答案 1 :(得分:0)

更改查询中的Contestant_votes列,以包含2个下划线(即:Contestant__votes)。然后,Cake automagic会将其作为参赛者阵列数据的一部分包含在内,如下所示:

Array (
    [Contestant] => Array (
        [id] => 1
        [name] => test
        [age] =>
        [city] => atest
        [telephone] => 
        [email] => test@test.com
        [why_model_house] => a
        [highschool] =>
        [photo] => 5329_119145013633_512383633_2487923_7196193_n0.jpg
        [active] => 1
        [votes] => 4
    )
    [Vote] => Array (
         [id] => 1
    )
)

答案 2 :(得分:0)

2个下划线不适用于所有型号?

 var $hasOne = array(

'评分'=&gt;阵列(    'className'=&gt; '评分',    'fields'=&gt;数组('SUM(Rating.score)AS Location__sum','AVG(Rating.score)AS Location__avg','COUNT(Rating.score)AS Location__count'),    'group'=&gt; 'Rating.location_id',   )  );

无法生成具有Location ['sum']

的结果集

答案 3 :(得分:0)

我带我三个小时的好时光。但我终于破解了它。

双下划线模式来自here。它是mysql数据库驱动程序的扩展,允许您执行add any calculated value as a field的扩展。

此外,我不得不在蛋糕的基本控制器中检查现场检查。 找到以第1000行开头的代码块:

if (!empty($options['order']) && is_array($options['order'])) {
    // lots of code goes here
}

用这个替换整个块(我为了简洁而切割它):

if (!empty($options['order']) && is_array($options['order'])) {
 $key = key($options['order']);
 $value = $options['order'][$key];

 $key = preg_replace('/[^a-zA-Z_.]/', '', $key);

 $options['order'] = array();
 $options['order'][$key] = $value;
}

此字段验证非常幼稚,基本上只应用白名单来避免任何简单的SQL注入,但您的用户将能够通过更改URL本身来搞乱查询。我只是将它用于内部后端,所以它现在必须要做。

我也偶然发现了这个链接,看起来在蛋糕1.3中会有一个不太常见的方法(上面的代码写的是1.2.5)