2011-03-05 44 views
3

我是Ruby/Rails的新手,所以这可能(希望)是一个简单的问题,我只是不知道答案。缓存Rails 3模型中的复杂计算

我实现在Rails的会计/计费系统,和我试图跟踪运行平衡的每次交易后,才能在视图下方显示它:

 
Date  Description  Charges($) Credits($) Balance($)
Mar 2 Activity C $4.00 -$7.50
Feb 25 Payment for Jan $8.00 -$3.50
Feb 23 Activity B $1.50 -$11.50
Feb 20 Activity A $2.00 -$10.00

每个事务(也称为订单项)存储在数据库中,除余额外,所有上述值(日期,说明,金额)均存储在数据库中。我无法将每笔交易的余额存储在数据库中,因为如果先前的交易发生某种情况(例如后来发布的付款失败),则可能会更改它。因此,我需要为每个订单项实时计算它,并且某个订单项的余额值取决于该订单项之前的订单项的值(余额=上一行项目的余额+此订单项的金额,即)

所以这是我的问题。这样做的我现在的(不称职)的方式是,在我的LineItem模型中,我有一个平衡的方法,该方法是这样的:

def balance 
    prev_balance = 0 
    #get previous line items balance if it exists. 
    last_line_item = Billing::LineItem.get_last_line_item_for_a_ledger(self.issue_date,self.ledger_item_id) 

    if last_line_item 
    prev_balance = last_line_item.balance 
    .. some other stuff... 
end 

prev_balance + (-1*net_amount) # net_amount is the amount for the current line item 
end 

这是超级昂贵的,我认为需要永远载入因为我计算上一页订单项的余额一次又一次。有什么更好的方法来做到这一点?

+0

您是否可以不为第一个LineItem调用余额,然后在迭代所有项目时跟踪当前余额? – Olives 2011-03-05 04:17:06

+0

有没有可以对'get_last_line_item_for_a_ledger'做任何优化,比如急切加载关联?你的数据库字段是否被索引? – 2011-03-05 04:32:42

+0

我有一个像你的系统,交易和余额,不是为了钱,而是为了股票。我直接在交易中保存余额。每次交易更新时,我都会更新所有下一笔交易,因此当我需要显示余额时,它已经被计算出来了。这不是默认实现,但可以在数据量很大并且性能非常重要时提供帮助。 – 2011-03-05 12:05:16

回答

3

你基本上是为不想在每次交易中存储余额而付出代价的。你可以用索引优化你的数据库并使用缓存等。但从根本上来说,如果您有很多交易,则会遇到计算余额需要很长时间的问题。

请记住,您将继续获得新的交易,并且随着时间的推移您的问题会变得更糟。

你可以考虑几种设计方案。首先,像Douglas Lise提到的那样,您可以在每笔交易中存入余额。如果有更早期的交易进入,这意味着您可能必须自该日起更新多个交易。但是,这有一个上限(取决于您希望允许的“旧”事务),因此它具有合理的最坏情况行为。

或者,您可以执行对帐步骤。每个月你都会在X周以上的交易中“结账”。对帐后,您存储您计算的余额。在def balance中,您现在使用您现有的逻辑,但也请参阅“与以前的调节相同”。这又提供了一个合理且可预测的最坏情况。