【问题标题】:CakePHP: paginating with search logic in a modelCakePHP:在模型中使用搜索逻辑进行分页
【发布时间】:2012-04-30 07:39:12
【问题描述】:
我在对搜索结果进行分页时遇到问题。我的设置如下。
我在myapp.com/searches/products 有一个搜索表单,其中包含视图(有搜索表单).../app/views/searches/products.ctp。我正在使用Searches 控制器,该控制器使用Product 模型进行此搜索查询。 Product 具有带有搜索逻辑 ($this->find(...)) 的操作 search()。搜索结果显示在视图中的表单下方。
如何执行类似于$this->paginate() 的操作,这通常在控制器中完成?此外,我想知道我的设置是否有问题,尤其是包含表单和搜索结果的视图。
【问题讨论】:
标签:
php
cakephp
pagination
cakephp-model
【解决方案1】:
将搜索逻辑保留在模型中并仍然在控制器中分页的一种方法是这样做:
说明:
不是从模型返回实际的结果,而是返回任何/所有找到的选项,然后像往常一样进行分页。对于某些示例,例如下面这个简单的示例,它可能看起来有点矫枉过正,但它为您的find() 添加更多选项留下了空间,例如contain、order、group、joins、conditions ......等等等等。并且更符合“胖模特,瘦控制器”的口头禅。
使用这样的选项设置您的find()s 也很不错,这样它就可以在您的整个网站中轻松重复使用 - 只需传递不同的选项,您就可以开始了。
代码:
/* CONTROLLER
*/
$opts = array('paginate' => true, 'limit'=>20);
$paginateOptions = $this->Event->getEvents($opts);
$this->paginate = $paginateOptions;
$data = $this->paginate('Event');
/* MODEL
*/
public function getProducts($opts = null) {
$params = array();
//limit
$params['limit'] = 50; //default
if(!empty($opts['limit'])) $params['limit'] = $opts['limit'];
//paginate option
$paginate = false;
if(isset($opts['paginate'])) {
if($opts['paginate']) $paginate = true;
}
//either return the options just created (paginate)
if($paginate) {
return $qOpts;
//or return the events data
} else {
$data = $this->find('all', $qOpts);
return $data;
}
}
有一些方法可以编写更精简/更少的代码行 - 但我喜欢这样写,所以它很快就可以理解。
(您的整体结构似乎没有任何问题。)
【解决方案2】:
我通常用于在会话中存储搜索参数并处理控制器操作中的所有内容。
function indexbystatus() {
$this->set('title_for_layout','List Assets by Status');
$this->Session->write('sender',array('controller'=>'assets','action'=>'indexbystatus'));
$searchkey=$this->Session->read('Searchkey.status');
$conditions='';
if($searchkey) {
$conditions=array('Asset.status_id'=>$searchkey);
}
if(!empty($this->data)) {
// if user has sent anything by the searchform set conditions and
// store it to the session but if it is empty we delete the stored
// searchkey (this way we can reset the search)
if($this->data['Asset']['status_id']!='') {
$conditions=array('Asset.status_id'=>$this->data['Asset']['status_id']);
$this->Session->write('Searchkey.status',$this->data['Asset']['status_id']);
} else {
$this->Session->delete('Searchkey.status');
$conditions=null;
}
} else if($searchkey) {
// if no data from the searchform we set the stored one
// from the session if any
$this->data['Asset']['status_id']=$searchkey;
}
$this->paginate=array(
'limit'=>25,
'order'=>array('Asset.status_id'=>'asc'),
'conditions'=>$conditions,
);
$this->set('assets',$this->paginate());
$statuses=$this->Asset->Status->find('list');
$this->set('statuses',$statuses);
}
我只是更喜欢在控制器动作而不是模型中处理它,因此我可以通过动作有不同的解决方案和逻辑。