2012-11-26 70 views
1

在我的應用程序中,用戶有重點。返回一組半最新記錄

每個Highlight都有一個HighlightType。所以,如果我跑user.highlights我可能會看到這樣的輸出:

example of user.highlights

注意,也有TYPE_ID 47.許多亮點,這標誌着用戶已經運行次數的里程碑。

我想要做的是返回這個完整的記錄列表,但每個highlight_type只包含一個突出顯示,並且我希望這一個記錄成爲最近的記錄(在本例中爲「第50次運行」突出顯示) 。所以在上面的例子中,我會得到相同的結果,但刪除了ID 195-199。

有沒有做到這一點的有效途徑?

+0

你有沒有試過'user.highlights.group('highlight_type_id')'? – MrYoshiji

+0

這似乎是「工作」,但我不確定它實際上在做什麼。 GROUP不會爲每個highlight_type_id返回一條記錄,但我不確定它使用什麼邏輯來選擇特定記錄。正如244an所暗示的那樣,當像user.highlights.group('highlight_type_id').order('created_at DESC')這樣的東西不能按預期工作時,因爲排序是在分組之後完成的。如果我能理解小組選擇記錄背後的邏輯,那麼我可以對這種方法更有信心。 – pejmanjohn

回答

1

我不認爲有一個簡單或乾淨的方法來實現這一點,也沒有「Rails的方式」。看看例如這link

根據一個建議,在link你會做這樣的SQL請求:

SELECT h1.* 
FROM highlights h1 
LEFT JOIN highlights h2 
ON (h1.user_id = h2.user_id 
    AND h1.highlight_type_id = h2.highlight_type_id 
    AND h1.created_at < h2.created_at) 
WHERE h2.id IS NULL AND h1.user_id = <the user id you are interested in> 
group by h1.highlight_type_id 

我認爲這將是一些性能問題,如果你有大的表,也許,一個又何嘗不是如此很乾淨,我認爲。

否則,如果不是我會做這樣的事情,用戶這麼多亮點:

rows = {} 
user.highlights.order('highlight_type_id, created_at DESC').each do |hi| 
    rows[hi.highlight_type_id] ||= hi 
end 
# then use rows which will have one object for each highlight_type_id 

上created_at的DESC是重要

編輯: 我也看到了一些建議基於此 user.highlights.group('highlight_type_id').order('created_at DESC') 這也是我第一次以爲應該解決的問題,但我測試了它,似乎沒有得到一個正確的結果 - 至少在我的測試數據。

+0

這裏的重點。我喜歡你的第二個建議,因爲它很容易理解。一個典型的用戶將有50個突出記錄,並且在上限處可能達到〜200條記錄。任何想法,如果這可能是一個性能問題? – pejmanjohn

+0

同樣對於我的特殊情況,我正在考慮在表格中添加一個標誌,我在這裏標記highlight_type_id的舊記錄。然後我可以過濾掉這些。似乎是一個更清潔的解決方案,你呢?無論哪種方式仍然好奇,如果有一個乾淨,高性能的方式解決這個沒有旗幟。 – pejmanjohn

+0

不知道你使用什麼服務器,但我們有4年的服務器。在一些地方,我們將多達20000行數據行的結果視爲沒有內存問題的模型對象。對於表演,只要有幾百行,我不認爲你會注意到它是否只有一百個。使用標誌看起來像是一個「乾淨的」解決方案,但這取決於該標誌總是正確的。我個人會使用「哈希解決方案」。我認爲「JOIN解決方案」可能會有不好的表現。 – 244an