2017-04-19 50 views
1

我有一个CakePHP 3应用程序,它有2个模型,UrlsDownloads。这些模型是相关联的,使得URL可以有多个下载(Cake中的Urls hasMany Downloads)。如何在CakePHP 3中分页查询子查询?

当我做一个查询像这样它就会从Urls表中返回1行以及所有相关Downloads的:

// This is in a view() method 
$query = $this->Urls->find()->contain(['Downloads' => ['sort' => ['Downloads.created' => 'DESC'] ] ])->where(['id' => $id]); 

我想分页的Downloads列表中,但无法看到如何做这个。我已经看到了在https://book.cakephp.org/3.0/en/controllers/components/pagination.html但我唯一能找到的东西,我试过是:

public function initialize() 
{ 
    parent::initialize(); 
    $this->loadComponent('Paginator'); 
} 

// In my view() method 
$this->paginate = [ 
    'contain' => ['Downloads'] 
]; 

$query = $this->Urls->find()->contain(['Downloads' => ['sort' => ['Downloads.created' => 'DESC'] ] ])->where(['id' => $id])->paginate(); 

,但它只是错误说 未知法“拼版”

+0

您可能希望再次仔细阅读文档,'paginate()'方法不是表类的方法。 – ndm

回答

0

既然你是只显示一行网址你可以做两个查询。

一个查询中获取的网址(不下载)

$url = $this->Urls->get($id); 

第二个取回(和分页!)的dowloads

$downloads = $this->Urls->Downloads->find() 
    ->sort(['created' => 'DESC']) 
    ->where(['url_id' => $id]); 

$downloads = $this->paginate($downloads) 
+0

我真的希望在1个查询中完成所有工作,因为能够使用'contains'的要点是你*不必*做单独的查询。谢谢你的信息。 – Andy

+1

蛋糕最终会做两个不同的查询来检索数据。所以我没有看到这一点 – arilia

0

由于下载所属的网址,你可以做相反,如下所示:

$downloads = $this->Urls->Downloads->find() 
    ->contain('Urls') 
    ->where(['url_id' => $id]) 
    ->order(['created' => 'DESC']); 
0

您的错误是因为paginate()不符合表类的hod,并且你在表对象上调用它,所以它是未知的。你需要把它的控制器对象: -

$this->paginate(); 

作为paginate是一个控制器方法,因为你是在你的榜样尝试它不能被称为查询检索的Url的一部分。这意味着您需要执行两个查询,但这是CakePHP如果包含下载内容就会失败的问题。例如: -

$this->Urls->get($id, ['contain' => 'Downloads']); 

这实质上导致以下两个查询,因为它不能在SQL中使用JOIN完成: -

$this->Urls->get($id); 
$this->Urls->Downloads->find('all')->where(['url_id' => $id])->all(); 

所以,你需要得到Url第一: -

$url = $this->Urls->get($id); 

然后进行分页要对下载的查找查询传递到您的PAGINATE方法下载: -

$query = $this->Urls->Downloads->find() 
    ->sort(['created' => 'DESC']) 
    ->where(['url_id' => $id]); 
$downloads = $this->paginate($query);