2011-07-05 69 views
0

表 - 聯繫人對外輸出「隨機」記錄

Name  Channel 
Teejay Friends 
John  Colleagues 
Rick  Friends 
Carl  Business 
Vulcan Business 
Scott Office 
Alex  Friends 

我怎麼出去放記錄從該表中,「隨機」。那麼,不完全random。我應該能夠輸出沒有相同記錄的記錄彼此相鄰。

A record in the `Friends` Channel 
A record in the `Colleagues` Channel 
A record in the `Business` Channel 
A record in the `Office` Channel 
A record in the `Friends` Channel 
A record in the `Business` Channel 
A record in the `Friends` Channel 

更多信息:

朋友模型,同事模式,商業模式,辦公模式有聯繫的兒童模特。

+0

如果什麼有更多的人比其他人。比「朋友」多於「同事」? –

+0

它將停止從朋友模型中檢索記錄。 –

+0

所以這是一個隨機的順序,而不是完全隨機的項目 –

回答

1

您對此有何看法?

[ Friend, Colleague, Business, Office ].each do |klass| 
    klass.find(:first, :offset => (klass.count * rand).to_i, :limit => 1) 
end 

這會從每個子模型中獲取一個條目。這會不會是那麼快,但工程:)

如果您需要兩個迭代,你可以將整個塊包裝成:

2.times do 
end 

但要注意模型的順序是固定在這裏的。如果你需要隨機還有:

prev = nil 
10.times do 
    klass = [ Friend, Colleague, Business, Office ].reject { |k| k == prev }.shuffle.first 
    p klass.find(:first, :offset => (klass.count * rand).to_i, :limit => 1) 
    prev = klass 
end 

更新

對於好奇,我做了一個小方法。請記住,如果您使用的是SQLite,則需要將RAND()更換爲RANDOM()。請檢查this question

def get_random_items(classes, count) 
    # collect at least count/2 random items from each class 
    items = Hash.new do |hash,klass| 
    hash[klass] = klass.find(:all, :order => "RAND()", :limit => (count.to_f/2).ceil) 
    end 

    results = [] 
    prev = nil 

    while (classes.length > 0 && results.length < count) do 
    klass = classes.shuffle!.pop 

    item = items[klass].pop 
    next unless item 

    classes << prev if prev 
    prev = (items[klass].length > 0) ? klass : nil 
    results << item 
    end 

    results 

end 

用法:get_random_items([ Friend, Colleague, Business, Office ], 10)