如何使用Kaminari Gem计算所有分页页面的总金额?
解决Kaminari分页下计算所有费用总额的问题
你当前的代码中,@expenses是分页后的数据集,仅包含当前页的10条记录,所以@expenses.map(&:total).sum只能得到当前页的费用总和。要计算所有分页数据的总费用,有以下几种高效的实现方式:
方法一:数据库层面直接计算(推荐)
利用ActiveRecord的聚合函数让数据库直接完成计算,避免加载所有记录到内存,性能最优。
修改控制器的index方法:
def index @expenses = Expense.order(:batch_id).page(params[:page]) # 直接在数据库中计算unit_price * quantity的总和 @total_all_expenses = Expense.sum('unit_price * quantity') # 保留当前页的总和(如果需要) @total_page_expenses = @expenses.map(&:total).sum end
如果你的unit_price或quantity是字符串类型,需要先转换为数值类型(不同数据库语法略有区别):
# PostgreSQL示例 @total_all_expenses = Expense.sum('unit_price::integer * quantity::integer') # MySQL示例 @total_all_expenses = Expense.sum('CAST(unit_price AS UNSIGNED) * CAST(quantity AS UNSIGNED)')
方法二:模型封装计算逻辑(适合复杂场景)
如果total方法包含更复杂的业务逻辑(不止简单相乘),可以在模型中定义数据库层面的计算方法,或者按需加载记录计算:
方式1:模型添加数据库计算方法
class Expense < ApplicationRecord belongs_to :batch paginates_per 10 def total unit_price.to_i * quantity.to_i end # 定义类方法计算所有记录的总费用 def self.total_all sum('unit_price * quantity') end end
控制器中直接调用:
def index @expenses = Expense.order(:batch_id).page(params[:page]) @total_all_expenses = Expense.total_all @total_page_expenses = @expenses.map(&:total).sum end
方式2:加载所有记录计算(仅数据量小时适用)
def index @expenses = Expense.order(:batch_id).page(params[:page]) @total_all_expenses = Expense.all.sum(&:total) @total_page_expenses = @expenses.map(&:total).sum end
⚠️ 注意:如果数据量很大(比如上万条),这种方法会加载所有记录到内存,影响性能,不推荐。
更新视图显示
修改视图中的金额展示部分,同时呈现总费用和当前页费用:
<div> Total Expense per page = <%= number_to_currency(@total_page_expenses, :unit => "Tshs. ", :delimiter => ",") %> </div> <div> Total All Expenses = <%= number_to_currency(@total_all_expenses, :unit => "Tshs. ", :delimiter => ",") %> </div>
内容的提问来源于stack exchange,提问作者ejoka
相关产品推荐
相关产品推荐

