2011-03-29 23 views
3

在我的應用程序用戶has_many手勢。計算用戶完成手勢後的幾天的好方法是什麼?最好的方法來計算一個非破的連續幾天

現在我正在像下面這樣做,它按照我的意願工作。但顯然它沒有規模。

class User < ActiveRecord::Base 

    # ... 

    def calculate_current_streak 
    return 0 unless yesterday = gestures.done_on_day(Date.today-1) 
    i = 0 
    while gesture = self.gestures.done_on_day(Date.today - (i+1).days).first 
     i += 1 
    end 
    i += 1 if gestures.done_on_day(Date.today).first 
    i 
    end 

end 

謝謝!特別指向一個誰可以在某種程度上工作,唯一的軌道工作日太:)

+0

你可以解釋一下數據庫表結構 - 你有一個手勢表,每個手勢的記錄和時間戳嗎? – Elad 2011-03-29 11:27:16

回答

2

想想這樣說:

連勝的長度相當於過去了(業務)的天數用戶沒有使用手勢的最後一個(商業)日,對吧?

因此,解決方案歸結爲計算用戶沒有做出姿態的最近一天。

爲了最簡單地做到這一點,有很多數據庫管理員都在使用它們:他們使用所有日期(例如,從2000年到2100年的所有日期)創建數據庫表。該表只需要日期字段,但您可以在布爾字段中標記非工作日,例如週末和假日。這樣的表可以方便地在很多的查詢,你只需要創建和填寫一次。 (Here's在這樣的表更詳細的文章,對MS SQL編寫的,但有見地的反正。)

有了這個表(我們稱之爲dates),就可以計算出使用類似的連勝預售日期(僞SQL) :

SELECT d.date 
FROM dates d 
LEFT JOIN gestures g ON d.date = g.date AND g.user_id = <put_user_id_here> 
WHERE d.date < TODAY() AND g.date IS NULL AND d.work_day = TRUE 
ORDER BY d.date DESC 
LIMIT 1 
+0

有趣的把戲。不知道是否比在內存中操作日曆對象更好,但它更容易。 – Jean 2011-03-29 12:59:08

相關問題