控制器.rb
def index
@expenses = Expense.all.order(:expense_type_id)
end
@expenses 如下所示
[#<Expense:0x00007faeb044c6e8
id: 1,
amount: 120
expense_type_id: 1>,
#<Expense:0x00007faeb044c2b0
id: 2,
amount: 1200
expense_type_id: 1>,
#<Expense:0x00007faeb044c2b0
id: 3,
amount: 11200
expense_type_id: 3>,
#<Expense:0x00007faeb044c2b0
id: 4,
amount: 1120
expense_type_id: 4>,
#<Expense:0x00007faeb044c2b0
id: 5,
amount: 1120
expense_type_id: 4>]
index.json.jbuilder
json.records do
json.array! @expenses do |expense|
json.amount expense.billed
json.id expense.id
json.expense_type_id expense.expense_type_id
end
end
现在从 index.json.jbuilder 文件返回的输出是
records = [{amount: 120, id: 1, expense_type_id: 1}, {amount: 1200, id: 2, expense_type_id: 1}, {amount: 11200, id: 3, expense_type_id: 3}, {amount: 1120, id: 4, expense_type_id: 4}, {amount: 1120, id: 5, expense_type_id: 4}]
但是我想要的输出是
records = [{amount: 120, id: 1, expense_type_id: 1}, {amount: 1200, id: 2, expense_type_id: 1}, {amount: sum of amount with expense_type_id 1, id: 'Subtotal', expense_type_id: nil}, {amount: 11200, id: 3, expense_type_id: 3}, {amount: sum of amount with expense_type_id 3, id: 'Subtotal', expense_type_id: nil}, {amount: 1120, id: 4, expense_type_id: 4}, {amount: 1120, id: 5, expense_type_id: 4}, {amount: sum of amount with expense_type_id 4, id: 'Subtotal', expense_type_id: nil}]
我想要插入一个 Subtotal 对象,以获取每个 expense_type_id 的所有费用。任何帮助表示赞赏。
我还没有使用 json builder。我已经用普通的 ruby 完成了,希望你能翻译成构建器格式。
# Grouping all records by expense_type_id, so that we can sum
records = @expenses.group_by{ |expense| expense[:expense_type_id] }
records.map do |expense_type_id, items|
# Initializing total as zero, so that we can sum inside loop. We can sum later in separate loop, but better to avoid many loops
total = 0
attributes = items.map do |item|
bill = expense.billed.to_f
total += bill
{
amount: bill,
id: expense.id,
expense_type_id: expense_type_id
}
end
# attributes will contain all formatted records, and lastly we insert our total
attributes << {amount: total, id: 'Subtotal', expense_type_id: nil }
end.flatten.compact # Since we are using double map, we get array of arrays, so need to flatten