在记录集合上使用 will_paginate 会更改分页结果计数?
Posted
技术标签:
【中文标题】在记录集合上使用 will_paginate 会更改分页结果计数?【英文标题】:Using will_paginate on a collection of records changes the paginated results count? 【发布时间】:2022-01-06 12:14:08 【问题描述】:我们有型号Subscription
和SubscriptionCart
。一个Subscription
has_many
SubscriptionCart
。
我们拥有并使用这两个模型之间的关系来获得 Subscription
最旧的购物车,其中 plan_id
更改为当前的 Subscription
plan_id
(换句话说,定义当前的第一个购物车Subscription
计划)
Subscription
关系如下:
has_one :first_version_with_current_plan, ->
joins(:subscription)
.where(subscription_carts: status: "processed" )
.where("subscription_carts.plan_id = subscriptions.plan_id")
.order("subscription_carts.authorized_at ASC")
, class_name: "SubscriptionCart", inverse_of: :subscription
上述关系将返回一个Subscription
(父级)和第一个购物车(子级),其中plan_id
更改为Subscription
plan_id
是什么。
我们在索引视图中使用该关系,我们使用will_paginate 来显示结果。
控制器:
def index
@subscriptions = current_account.subscriptions
.includes(:first_version_with_current_plan)
.order("subscription_carts.authorized_at ASC") # relation attribute
.paginate(page: params[:page], per_page: 20)
end
问题我们遇到的问题是,在 .paginate
方法之前,@subscriptions.count
将返回 50,但将 .paginate
应用于集合会在视图中呈现少于 10 个总结果。
我怀疑will_paginate
在幕后进行了第二次查询,这会破坏结果计数,但我不确定,因为我在网上找不到太多信息。
对此有任何解释或任何已知的解决方法吗?
【问题讨论】:
【参考方案1】:分页应该改变计数 - 重点是通过应用限制和偏移来限制从数据库中获取的数据量。分页时,计数始终等于或小于 per_page
设置 - 毕竟您只是从表中获取那么多行。
如果您想计算记录总数,您需要在没有分页的范围内创建单独的计数查询:
def index
scope = current_account.subscriptions
.includes(:first_version_with_current_plan)
.order("subscription_carts.authorized_at ASC")
@count = scope.count
@subscriptions = scope.paginate(page: params[:page], per_page: 20)
end
如果您想计算记录总数,您需要在没有分页的范围内创建单独的计数查询,或者在模型上使用计数器缓存。
【讨论】:
我认为我的解释不正确。我知道在使用will_paginate
时,count
将返回与per_page
参数一样多的记录,因为这是页面中“适合”的内容。我遇到的问题是分页前后的结果不一样。如果 @subscriptions
的总大小为 50 条记录,则在该集合上使用 .paginate
会将记录总数更改为 10 或更少。所以 50 条记录变得少于 10 条,好像查询完全不同。
换句话说,我在控制台上运行相同的查询并获得 50 个结果,但应用 .paginate
会显示 10 条记录中的 10 条记录,而不是 3 页的 20、20 和 10 个结果。这就是为什么我认为第二个查询正在幕后发生。
如果您有 50 条记录和 20 页限制并且在第 3 页上,则您有 OFFSET 40 LIMIT 20 所以它完全符合逻辑,您得到 10 的计数。它不会创建 3 个不同的查询作为那将是非常无效的。
我意识到标题中的问题有点误导。错误的不仅仅是count
。这是在集合上应用.paginate
后返回的整个数据集。如果范围在控制台上返回 50 条记录,我希望对其应用分页会导致相同的记录根据 per_page
参数划分为所需的页数。但我得到的是与我在控制台上得到的完全不同的记录数据集,最明显的是分页结果的总数少于我在控制台上得到的总数。
编写一个模型测试来复制您期望得到的结果。但我仍然认为你把它弄反了。分页实际上并没有给你分成页面的结果——它只是根据预先计算的偏移量给你那个页面。要获取其他页面,您需要执行更多查询。以上是关于在记录集合上使用 will_paginate 会更改分页结果计数?的主要内容,如果未能解决你的问题,请参考以下文章
在 Rails 中使用 will_paginate 和 AJAX 实时搜索和 jQuery
Rails 5.2 上 jquery DataTables 和 will_paginate gem 的分页问题