如何在 rails 中循环时将对象插入对象数组

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

控制器.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 的所有费用。任何帮助表示赞赏。

arrays ruby-on-rails ruby object
1个回答
0
投票

我还没有使用 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
© www.soinside.com 2019 - 2024. All rights reserved.