使用 group by 和 Rails 的复杂分页场景

问题描述 投票:0回答:2

我有一个可能有 9000 多行的表,我正在尝试对其进行分页(使用 Kaminari),但在尝试找出如何分页时遇到问题。

在我的场景中,我有一家电子商务商店,我的客户可以请求将订单资金转移到他们的 PayPal。

我的型号如下:

# customer.rb

has_many :transfers, through: :orders
# order.rb

belongs_to :customer
has_one :transfer
# transfer.rb

belongs_to :order
belongs_to :customer

我正在尝试对所有转账进行分页,但按客户分组。我目前可以通过以下方式做到这一点:

# transfers_controller.rb

@transfers = Transfer.includes(:order, :customer)

然后在我看来循环它们,例如:

# index.html.erb

@transfers.group_by(&:customer).each

这很好用,我可以循环按客户分组的转账。也就是说,直到我遇到显示大量结果并因此需要分页的问题。

我当然可以轻松地使用 Kaminari 进行分页,例如:

@transfers = Transfer.includes(:order, :customer).page(params[:page])

问题是我的

group_by
有点螺丝。我可能会循环访问某个客户,并且可能不会包含所有传输,因为它达到了每页限制,这是误导性的。在我看来,我需要确保当我按客户分组时,我至少可以看到该客户的所有转账。

我知道 Kaminari 也有数组的分页方法,所以我可以这样做:

@paginatable_array = Kaminari.paginate_array(@transfers.group_by(&:customer)).page(params[:page]).per(10)

然后在我看来:

# index.html.erb

@paginatable_array.each

但是这个方向的问题是我仍然需要最初查询所有行,因此最终整个查询必须在 9000 多行上运行,因此分页根本没有帮助我。

在这种情况下,有关如何分页以便我可以优化此查询/页面的任何帮助吗?

更新

不知道为什么我没有想到这一点,脑子放屁?但对我来说最简单的方法是按客户查询,就像在我的控制器中一样:

@customers = Customer.includes(:orders, :transfers).page(params[:page])

然后在我看来:

@customers.each do |customer|
  customer.transfers.each do |transfer|
    # do stuff
  end
end

这样,当我分页时,我正在对客户进行分页。

ruby-on-rails ruby group-by pagination kaminari
2个回答
0
投票

从数据库加载时,我会按

customer_id
对记录进行排序,这应该将属于同一客户的记录保留在每个页面上。

# in the controller
@transfers = Transfer
               .includes(:order, :customer)
               .sort(:customer_id)
               .page(params[:page])

# in the view
@transfers.group_by(&:customer).each 

0
投票

通过帖子更新回答了原来的问题,但也在这里发帖:

不知道为什么我没有想到这一点,脑子放屁?但对我来说最简单的方法是按客户查询,就像在我的控制器中一样:

@customers = Customer.includes(:orders, :transfers).page(params[:page])

然后在我看来:

@customers.each do |customer|
  customer.transfers.each do |transfer|
    # do stuff
  end
end

这样,当我分页时,我会对客户进行分页,并且在循环时分页不会中断客户的传输。

© www.soinside.com 2019 - 2024. All rights reserved.