提问人:user12763413 提问时间:5/19/2023 更新时间:5/19/2023 访问量:66
如何在 rails 中循环时在对象数组中插入对象
How to insert an object in an array of object while looping in rails
问:
控制器.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}]
我想要插入一个小计对象,以获取每个expense_type_id的所有费用。任何帮助都是值得赞赏的。
答:
0赞
Biki Maharjan
5/19/2023
#1
我没有使用过json生成器。我已经用普通的红宝石完成了,希望你能翻译成构建器格式。
# 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
0赞
Les Nightingill
5/19/2023
#2
我会采用面向对象的方法,通过定义一个名为的类(也许你的应用程序中已经有这个,因为我看到了一个变量)......ExpenseType
expense_type_id
Expense.all.group_by(&:expense_type_id).map do |type_id, expenses|
ExpenseType.from_list(type_id,expenses).to_json
end
现在,实例数组可以负责聚合和格式化其 json 表示形式,如下所示......ExpenseType
# expense_type.rb
class ExpenseType
attr_accessors :type_id, :list
def self.from_list(type_id, list)
new(type_id, list)
end
def initialize(type_id, list)
@type_id = type_id
@list = list
end
def to_json
# skipping the detail here
# make a json representation of the list of expenses with this expense_type_id by calling .to_json on each
# followed by a json representation of the sum for this expense_type_id
end
end
最后,每个对象都知道如何将自己表示为 json:Expense
# expense.rb
class Expense < ApplicationRecord # I assume it's a model in a Rails app
def to_json
# return json representation of a single expense
end
end
评论
expenses_by_type: [{expense_type_id: 1, sub_total: 2000, expenses: [{each expense that is part of this}]} ]
expenses: [{id: 1, amount: 120, expense_type_id: 3}, {...}, ]