2011-03-05 58 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中,您現在使用您現有的邏輯,但也請參閱「與以前的調節相同」。這又提供了一個合理且可預測的最壞情況。