CakePHP分页。保持模特脂肪

时间:2012-11-08 17:40:58

标签: cakephp pagination cakephp-appmodel

我目前在我的模型(Referer Model)中有这个:

public function getReferers($type = 'today') {
    if ($type == 'this_month') {
        return $this->_getThisMonthsReferers();
    } elseif ($type == 'today') {
        return $this->_getTodaysPageReferers();
    }      
}

private function _getThisMonthsReferers() {
    $today = new DateTime();

    return $this->Visitor->find('all', array(
        'fields' => array(
            'Referer.url',
            'COUNT(UserRequest.visitor_id) as request_count',
            'COUNT(DISTINCT(Visitor.id)) as visitor_count',
            'COUNT(UserRequest.visitor_id) / COUNT(DISTINCT(Visitor.id)) as pages_per_visit',
            'COUNT(DISTINCT(Visitor.id)) / COUNT(UserRequest.visitor_id) * 100 as percent_new_visit'
        ),
        'joins' => array(
            array(
                'table' => 'user_requests',
                'alias' => 'UserRequest',
                'type'  => 'RIGHT',
                'conditions' => array(
                    'UserRequest.visitor_id = Visitor.id'
                )
            )
        ),
        'conditions' => array(
            'Visitor.site_id' => $this->Site->id,
            'MONTH(UserRequest.created)' => $today->format('m'),
            'YEAR(UserRequest.created)' => $today->format('Y')
        ),
        'group' => array(
            'url'
        )
    ));
}

问题在于我如何对此进行分页。如果只是将我的代码从模型中复制到控制器中,那将是如此简单。问题是我希望在我的模型中保留查询。

这应该如何在CakePHP中完成?

2 个答案:

答案 0 :(得分:1)

自定义查找类型是一种方法。您可以在此处找到更多信息:http://book.cakephp.org/2.0/en/core-libraries/components/pagination.html#custom-query-pagination

要将_getThisMonthsReferers转换为自定义查找,请按此http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#creating-custom-find-types

例如:

// model
protected function _findThisMonthsReferers($state, $query, $results = array()) {
    if ($state === 'before') {
        $query['fields'] = ....
        $query['joins'] = ....
        return $query;
    }
    return $results;
}

// controller
public $paginate = array('findType' => 'thisMonthsReferers')

编辑:

我认为应该是:

public $paginate = array('thisMonthsReferers');

然而,我从这个答案中得到的解决方案是将其添加到我正在使用的方法

$this->paginate = array('thisMonthsReferers');

因为我不希望我在所有的行动中使用。然后像这样对模型进行分页。

$this->paginate('Visitor);

答案 1 :(得分:1)

不是返回find的结果,而是返回它的选项数组:

return array(
    'fields' => array(
    //...etc

然后使用这些选项在控制器中进行分页。关于此类似问题的答案的更多详细信息:Paginate from within a model in CakePHP

它仍然保持模型胖(使用任何可能改变条件,连接,字段等的逻辑)和控制器skinny,它只使用返回的数组作为分页选项。