2017-09-19 2 views
0

ランダムにデータベースからレコードを選択して、自分のビューに表示しようとしています。キャッチは、すべてのレコードが少なくとも1回選択されるまで、選択したランダムレコードを繰り返すことは望ましくありません。たとえば、テーブルに10個のレコードがあるとしましょう。ランダムレコードを1つ選択し、他の9個のレコードが少なくとも1回選択されるまでランダムに選択されたレコードが再度選択されないようにします。レールでランダムレコードを選択する

スニペット:

offset = rand(Quote.count) 

    @qotd = Rails.cache.fetch("term", :expires_in => 6.seconds){ Quote.offset(offset).first } 

答えて

0

すでに表示されているレコードを現在のプロセス外に保存するには、別の場所が必要です。プロセスが停止するか、複数のプロセスが稼動していることがあります(実稼働環境であれば、間違いなくそうする必要があります)。

tadman proposedとは対照的に、これは新しいレコードの追加をより複雑にするため、データベースにシーケンスを格納することをお勧めしません。

代わりに、単純なdisplayed(ブール値)の列(または別の表)とrely on what has been proposed in a different threadを追加して、特定のユースケースに味を付けました。だから、クエリは次のように次のようになります。

@qotd = Quote.where(displayed: false).order("RAND()").limit(1) 

もちろん

@qotd.update_attribute :displayed, true 

後に。

候補が見つからない場合は、すべてのレコードのdisplayed列をリセットする必要があります。おそらく単一のメソッド内で(クエリ、更新、リセット)が発生するはずです。

+0

'order(" RAND() ")'は、そのテーブルがかなり大きい場合、または頻繁にそのクエリにヒットしている場合、データベースサーバーに呼び出しを設定します。 – Grocery

2

使用状況を追跡する必要がある場合は、あなたが必要なものをランダムな値でそれを埋める、シーケンス列のいくつかの種類で、あなたがそれらを使用してそれらをNULL。それらがすべてNULLになったら、ランダムな値で再度シードし、それをもう一度やり直してください。

0

テーブルに「display_count」のような列を追加することをお勧めします。あなたが表示するために、ランダムなアイテムを取得したいときは、単純に次のようなクエリを発行することができます:あなたはいつも以上に表示された項目を選択

quote = Quote.where(
    display_count: Quote.select("MIN(display_count)") 
).order("RANDOM()") 
quote.update_attribute(:display_count, quote.display_count + 1) 

その方法を、あなたはそれを取得した後、それをインクリメント。これは、(ほぼ)このコードを実行するたびに、新しい項目を取得することを保証する必要があります。

関連する問題