我可以对自定义查询进行分页而不覆盖默认分页吗?

发布于 2024-12-06 21:26:10 字数 336 浏览 1 评论 0原文

在我的 CakePHP (1.2) 应用程序中,我有两个都使用分页的操作 - 索引和搜索。

在上一个问题中,我了解到,为了对搜索结果应用阈值分数,我需要使用 HAVING MySQL 关键字。由于 CakePHP 本身不支持此功能,因此我需要下拉到自定义查询才能完成此操作。

我能找到的所有自定义查询分页指南都涉及重写 paginate()paginateCount() 方法。

然而,由于我仍然希望能够在索引上正常分页,因此我不想更改模型中的正常分页行为。

有什么办法可以让我(咳咳)既能吃蛋糕又能吃蛋糕吗?

In my CakePHP (1.2) app, I have two actions that both use pagination - index and search.

In a previous question I learnt that, in order to apply a threshold score to search results, I need to use the HAVING MySQL keyword. Since CakePHP does not support this natively, I need to drop down to a custom query in order to accomplish this.

All the guides I can find to custom query pagination involve overriding the paginate() and paginateCount() methods.

Since I still want to be able to paginate normally on the index however, I don't want to change the normal pagination behaviour in the model.

Is there any way I can (ahem) have my Cake and eat it too?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海螺姑娘 2024-12-13 21:26:10

实际上,如果你可以用 find 来做到这一点,你也可以用 paginate 来做到。你可以看看这里

但是更具体地说,你可以添加条件/您在查找分页功能时使用的限制/字段/包含/顺序等。

我没有在分页中使用组,但它应该有效:D

在你的情况下,你会得到这样的结果:

$this->paginate = array(
   'fields' => array(
        'Product.category_id',
        'COUNT(Product.hotel_id) as total'
    ),
   'group' => array(
        'Product.category_id HAVING COUNT(Product.hotel_id) > 1')
    )
);

$data = $this->paginate('Product');

希望它有效,发表对你的结果的评论,如果它不起作用,你将不得不覆盖它,因为它不接受组条件...尽管我认为它会起作用,因为分页最终是一个发现。

编辑:

您可以尝试执行以下操作:

覆盖 paginate() 和 paginateCount() 但通过调整,隐藏一个条件,以便您可以判断它是否是具有或不具有的分页。像这样的事情:

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()){
   //if no having conditions set return the parent paginate 
   if (empty($conditions['having'])
       return parent::paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra)
   //if having conditions set return your override

//override code here

}

然后你在 paginateCount() 中做类似的事情,这样你就可以进行选择性分页。记住在不需要时取消设置 $conditions['having'] 或记住将其放在不影响您的查找的地方;)

Actually if you CAN do it with find you CAN do it with paginate. You can take a look here

But to be more especific you can add the conditions/limit/fields/contain/order etc that you use in find to the paginate function.

I haven't use group in the paginate but it SHOULD work :D

In your case you will have something like this:

$this->paginate = array(
   'fields' => array(
        'Product.category_id',
        'COUNT(Product.hotel_id) as total'
    ),
   'group' => array(
        'Product.category_id HAVING COUNT(Product.hotel_id) > 1')
    )
);

$data = $this->paginate('Product');

Hope it works, post a comment of your result, if it doesn't work you will have to override it, because it is not accepting the group condition... though I think it will work since pagination is a find in the end.

EDIT:

You may try to do something like this:

Override the paginate() and paginateCount() but with a tweak, sneak a condition so you can tell if its a pagination with having or not. Something like this:

function paginate($conditions, $fields, $order, $limit, $page = 1, $recursive = null, $extra = array()){
   //if no having conditions set return the parent paginate 
   if (empty($conditions['having'])
       return parent::paginate($conditions, $fields, $order, $limit, $page, $recursive, $extra)
   //if having conditions set return your override

//override code here

}

Then you do something similar in paginateCount(), that way you have a selective paginate. remember to do unset $conditions['having'] once it is not needed or remember to put it somewhere that doesn't affect your find ;)

浅唱ヾ落雨殇 2024-12-13 21:26:10

事实上,让这个工作比你想象的更令人头疼。

虽然我基本上遵循了 api55 的建议(谢谢!),但我也跳过了许多其他障碍:

  • 它是 不可能 这样做parent::paginateCount()。我通过使用 不同的 (显然更好)app_model.php 中的版本

  • 因为 paginateCount() 只是 find('count') 的包装器,所以它不接受 fields 参数。这对我来说很棘手,因为我依靠它来挤入我的派生列(全文搜索的分数)。我通过将 fields 的值两次传递给 paginate 来解决这个问题 - 一次作为 fields 一次作为“sneaky” ”。 Cake 将它无法识别的任何参数放入 extra 数组中。

  • 将其结合在一起,我在模型中重写了 paginateCount() ,以查看 extra 是否有一个名为“sneaky”的键。如果是,它会执行 find('all') 并使用 sneaky 的内容来填充字段。

在像今天这样的日子里,我必须退后一步,记住使用框架的所有优点。

Actually getting this to work was more of a headache than you might reasonably expect.

Although I basically followed the advice of api55 (thanks!) I also jumped a load of other hurdles:

  • It's not possible to do parent::paginateCount(). I overcame this by overriding it with a different (and apparently better) version in app_model.php.

  • Because paginateCount() is just a wrapper for find('count'), it doesn't accept a fields parameter. This is tricky for me as I rely on this to squeeze in my derived column (score of a full-text search). I got over this by passing the value of fields twice to paginate - once as fields and once as "sneaky". Cake puts any parameters it doesn't recognize into the extra array.

  • Tying this together, I had an override of paginateCount() in my model that looks to see whether extra has an key called "sneaky". If it does, it does a find('all') and uses the contents of sneaky to populate fields.

It's days like today that I have to step back and remember all the good points about using a framework.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文