2011-09-14 23 views
1

對於集Foobars與以下ID標識:選擇7項與集中在ID「N」

1 2 3 5 7 9 11 15 18 19 22 23 

我需要一種方法來與下面的IDS,基於ActiveRecord的返回Foobars:

baz(1) -> 1 2 3 5 7 9 11 

baz(9) -> 3 5 7 9 11 15 18 

baz(22) -> 9 11 15 18 19 22 23 

這必須與Ruby on Rails 2.3.9(no Arel)兼容。它不能通過簡單地從id n中減去並添加3來完成,因爲ID中可能存在空白。

編輯:這是我最後還是沒買:

firstseg = Foobar.all(:conditions => ["id <= " + params[:id]], 
    :limit=> 4, :order => "id desc").reverse 

@Foobars = firstseg + Foobars.all(:conditions => ["id > " + params[:id]], 
    :limit => (7 - firstseg.length).to_s, :order => "id asc") 

render 'showthem' 
+0

請更明確有關巴茲方法應與參數做什麼。另外,它是否總是使用ID的排序列表? – Kelvin

回答

2

試試這個:

class Foo 
    def snow_white_and_six_dwarfs 
    [ 
     Foo.all(:conditions => ["id < ?", id], :limit => 3, :order => "id ASC"), 
     self, 
     Foo.all(:conditions => ["id > ?", id], :limit => 3, :order => "id ASC") 
    ].flatten 
    end 
end 

現在

foo.snow_white_and_six_dwarfs 

OR

Foo.find(9).snow_white_and_six_dwarfs 
+0

這很棒,非常接近我最終做的事情(請參閱我的編輯)。 – ssnkl

+0

很好的答案(例如!),+1 – apneadiving

0

不知道是否有更好的方法,但你可以做總是做這樣的事情:

def baz center_id 
    all_ids = Foobar.find(:all, :select => "id", :order => "id ASC").collect &:id 
    center_index = center_id ? all_ids.index(center_id) : nil 

    if center_index 
    Foobar.find(all_ids[center_index-3..center_index+3]) 
    else 
    [] 
    end 
end 

這方式,您使用排序的id的索引而不是id本身。但要小心,如果你的中心索引小於3,你將有負指數,所以它會從數組的末尾選擇ID。

+1

如果你的'foobar'表中有幾百萬行,這個解決方案將會使你的數據庫和Web服務器停機。所有'發現者應該總是使用一個狹窄的過濾器或分頁來限制返回的行數。確實是 –

+0

。你的解決方案要好得多。 –