我在seeds.rb文件中生成了大量嵌套对象并且遇到了问题。除了绑定到父对象的属性外,所有对象都是正确创建的。在以下文件中:
seeds.rb
accounts.each do |i|
80.times do |j|
type = types.sample
case (type)
...
end
t = AcctTransaction.new
t.account_id = i.id
t.transaction_type_id = type
t.description = description
t.amount = amount
# keep transaction in chronological order unless it's the first one
unless AcctTransaction.exists?(account_id: t.account_id)
t.date = rand(i.date_opened..Time.now)
else
t.date = rand(AcctTransaction.where(account_id: t.account_id).last.date..Time.now)
end
t.adjusted_bal = i.balance + t.amount
i.update_attribute :balance, t.adjusted_bal
t.save
account_transactions << t
end
end
Rake db:seed运行没有错误,每个帐户生成80个事务(总共约12000个事务)。 唯一的问题是为 adjusted_bal (AcctTransactions模型)生成的值以及余额(帐户模型)的更新值不正确。他们只需要反映当前余额+交易金额的计算。
我的计算或循环本身是否有问题,或者我使用错误的方法将这些计算值分配给各自的模型?我已经尝试过这100种不同的方式而没有运气。请帮忙。
这是Rails 4.1.8 / Ruby 2.1.5。谢谢。
修改
澄清..
种子文件的这一部分应该执行以下操作:
- 对于每个帐户(已分配到“帐户变量”并使用“i”迭代),生成80个唯一交易
- 将交易金额添加到帐户的当前余额
- 将该值存储为AcctTransactions表中的“adjusted_bal”,并使用此值更新Accounts表中的“余额”
- 循环运行80次,每次“平衡”应该不同 - 已经被前一次迭代修改过。
醇>示例
第一次迭代:
- 原始帐户余额为100(例如)。
- 交易金额(随机)为-50。
- ( - 50)+ 100 = 50.这会作为adjust_bal
存储在交易中- 此外,帐户模型的余额列更改为“50”,因为这是帐户的新余额。
第二次迭代:
- 现在帐户余额为50(已由最后一次事务循环迭代更新)
- 交易金额(随机)为25。
- 25 + 50 = 75.这作为adjust_bal
存储在交易中- 此外,帐户模型的余额列也会更改为“75”,因为这是帐户的新余额。
(这样做80次)
希望更清楚。感谢
修改 (不正确)结果的屏幕截图...
从此屏幕剪辑(放大)可以看到,标题中的帐户余额为1073.62美元。在每笔交易中,余额列(来自acct_transaction模型的 adjusted_bal )完全是金额从$ 1073.62中扣除 - 意味着该帐户平衡永远不会改变。
答案 0 :(得分:2)
我不确定您的代码有什么问题,对我来说似乎不错,但是请允许我为您清理一下,它应该也能更快地工作,因为它可以减少查询,可能帮助你找出问题所在..也许lol
accounts.each do |account|
80.times do # no need for iterator
type = types.sample
case (type)
# ...
end
# this will save and insert the new transaction in the collection
# at the same time
# will save you the second query that updates the relation
account_transactions.create do |transaction|
transaction.account_id = account.id
transaction.transaction_type_id = type
transaction.description = description
transaction.amount = amount
transaction.adjusted_bal = account.balance + transaction.amount
# doing a first_or_initialize, will save you one query
# in loops where the record actually exist
transaction.date =
(t = AcctTransaction.where(account_id: t.account_id).first_or_initalize).persisted? ?
rand(account.date_opened..Time.now) :
rand(t.date..Time.now)
end
end
# save only once after the 80 loops, before moving to the next account
# could save you up to 80 queries in each loop
account.save
end