2011-07-05 34 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)