从CakePHP中的模型中分页

时间:2011-06-28 05:13:35

标签: cakephp model cakephp-1.3 paginate

我的Event模型中有一个名为getEvents的函数 - 您可以通过限制,startend日期,fields,{{1} } event和事件types

我读到subtypes可以接受我正在使用的所有参数,例如paginatejoinsconditions ...等正常{{1}可以。

当我不尝试分页时,它返回数据就好了。但是 - 我希望能够传递一个limit变量来告诉它而不是这样做:

find

这样做:

paginate

但是,当我尝试这样做时,它给了我很多错误。如果需要,我可以稍后指定错误 - 现在,我想我正在寻找 - 这是可以做到的吗?如果是这样,怎么样?

还有另一种更好的方式来做这样的事吗?我花了足够的时间让这个功能做我想要的,并允许所有选项传递...等 - 如果我不能用它进行分页,这似乎是浪费。但是 - 如果它不理想,我也能听到。提前谢谢。

修改

我在线阅读其他内容,表示你不应该在模型中使用paginate,因为它是从URL变量中提取的,这会破坏MVC结构的目的。这是有道理的,但这是否意味着我必须在模型和控制器中编写相同的连接/查询?在每一个需要它的行动中?

4 个答案:

答案 0 :(得分:9)

我想出如何在我的模型中保留我的复杂find而不必在控制器中第二次重写它的方式是传递一个$paginate布尔变量。

如果$paginate为真,则只返回创建的选项,然后可以在控制器的分页中使用。如果它是假的(意味着我们不想分页),它将返回实际的事件结果。到目前为止,这似乎有效。

在我的getEvents()函数中(此方法在事件模型中)

    if($paginate) {
        return $qOpts; // Just return the options for the paginate in the controller to use
    } else {
        $data = $this->find('all', $qOpts); // Return the actual events
        return $data;
    }

然后,在我的事件/索引(事件控制器,索引操作 - 我知道我想要分页)中:

$this->Event->recursive = -1; // (or set recursive = -1 in the appModel)
$opts['paginate'] = true;

$paginateOptions = $this->Event->getEvents($opts);

$this->paginate = $paginateOptions; // Set paginate options to just-returned options
$data = $this->paginate('Event'); // Get paginate results
$this->set('data', $data); // Set variable to hold paginated results in view

答案 1 :(得分:3)

paginate()模型方法接受与find()相同的参数。具体来说,find()需要一系列选项,但paginate()希望每个选项都单独传递。请参阅CakePHP书中的Custom Query Pagination

所以,而不是:

$data = $this->paginate($qOptions);

你想要这样的东西:

$data = $this->paginate($qOptions['conditions'], $qOptions['fields'], ...);

修改

自定义模型分页不是您调用的函数。它是您需要实现的函数,将由CakePHP框架调用。在您的问题示例中,您尝试从模型中的某个位置手动调用$this->paginate(...)。这不起作用。相反,这样做。

在您的模型中,实施paginatepaginateCount方法。

function paginate($conditions, $fields, ...)
{
    // return some data here based on the parameters passed
}

function paginateCount($conditions, ...)
{
    // return some rowcount here based off the passed parameters
}

然后,在您的控制器中,您可以使用标准分页功能。

function index()
{
    $this->paginate = array('MyModel' => array(
        'conditions' => array(...),
        'fields' => array(...),
    ));

    $this->set('myobjects', $this->paginate('MyModel'));
}

现在,Controller::paginate()函数会从Controller::paginate参数中获取条件和其他数据,而不是将其传递给Model::find,它会将其传递给您的自定义{{1} }和Model::paginate()函数。因此,返回的数据基于您在这两种方法中执行的操作,而不是基于标准Model::paginateCount()。     }

答案 2 :(得分:-1)

$ paginate 数组类似于Model-> find('all')方法的参数,即:条件,字段,顺序,限制,页面,包含,连接和递归的。

所以你可以这样定义你的条件:

var $paginate = array(
 'Event' => array (...)
 );

或者您也可以在操作中的$ paginate数组中设置条件和其他键。

 $this->paginate = array(
 'conditions' => array(' ... '),
 'limit' => 10
 );
 $data = $this->paginate('Event');

您在控制器中使用$name = 'Event'吗?

如果我们不在$this->paginate()中提及模型名称,它将使用$name中提到的模型,否则查看var $uses数组,其中将获得模型名称(第一个)

表示例如var $uses = array('Model1','Model2'); // $ name!=提到

你想要对 Model2 进行分页,那么你必须在paginate数组中指定ModelName,如$this->paginate('Model2'),否则将在分页中考虑Model1。

答案 3 :(得分:-1)

你可以使用这个适合我的那个。

$ condition =“你的条件”;  $ this-> paginate = array(                             'fields'=> array('AsinsBookhistory.id','AsinsBookhistory.reffer_id','AsinsBookhistory.ISBN','AsinsBookhistory.image','AsinsBookhistory.title','AsinsBookhistory.last_updatedtime'),                             'conditions'=> $条件,                             'group'=>阵列( 'AsinsBookhistory.ISBN'),                             'order'=>数组('AsinsBookhistory.last_updatedtime'=>'desc')                                 ); $ this-> set('lastvisitedbooks',$ this-> paginate('AsinsBookhistory'));