2012-06-27 38 views
3

我有一個Rails引擎,它在選擇的模型上定義了一個類方法top(count)。該方法所做的是在Redis中從有序集(ZSET)中獲取ID爲count的ID。這個想法是,這個模型的每個項目都有一個分數,這種方法是返回「最好」的記錄。該方法本質上是這樣的:我怎樣才能得到一個ActiveRecord ::關係從一個特定的ID序列排序的記錄數組?

def self.top(count = 1) 
    ids = redis.zrevrange(self.score_set, 0, count - 1) 
    items = self.find ids 

    if count == 1 
    return items.first 
    else 
    return items.sort { |x, y| ids.index(x.id) <=> ids.index(y.id) } 
    end 
end 

正如你所看到的,我目前在事後的記錄,因爲數據庫(或適配器)往往不會由多個ID找到時維持秩序排序。例如,Model.where('ID IN (?)', ids)將按升序ID進行排序,而不是通過傳遞ID的順序。

排序項目返回Array,但我希望此方法返回ActiveRecord::Relation,以便我的用戶可以鏈接其他ActiveRecord查詢方法。有沒有一種方法可以使用內置的ActiveRecord查詢方法來維護ID數組的順序?或者,有沒有辦法從一組記錄中構建一個ActiveRecord::Relation

回答

4

它確實取決於您使用的底層數據庫。我不認爲鐵軌有一個很好的方法來做到這一點。

我有一個應用程序,我在做你和你一樣的事情。將ID存儲在Redis ZSET中,然後按照該順序讀取它們。由於我們使用MySql,因此我們可以利用field function。注意:請確保您的order變量已被消毒!

+0

這對MySQL很好,是的,但我的寶石需要是數據庫不可知的。我想我可能會放棄,只是返回一個數組。我認爲沒有辦法做到這一點,適用於每個主要數據庫。 – davidcelis

+0

還有另一種方式,效率不高,但仍然可以完成這項工作:http://stackoverflow.com/a/15564039/204452 – swlkr

相關問題