在rails中选择随机记录

时间:2017-09-19 19:20:46

标签: mysql ruby-on-rails ruby controller

我正在尝试从数据库中随机选择一条记录并将其显示在我的视图中。问题是我不希望重复所选的随机记录,直到所有记录至少被选中一次。例如,让我们说我的表有10条记录,所以我想选择任意一条随机记录,并确保在选择其他9条记录至少一次之前,不再选择该随机选择的记录。

片段:

    offset = rand(Quote.count)

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

3 个答案:

答案 0 :(得分:2)

如果你需要跟踪用法,那么你需要的是某种序列列,用随机值填充它,并在你使用它们时将它们取出来。当它们全部为NULL时,使用随机值重新种子并重新执行。

答案 1 :(得分: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列。所有这些,(查询,更新和重置)应该可能在一个方法中发生。

答案 2 :(得分:0)

我的建议是添加一个类似" display_count"到你的桌子。当您想要显示随机项时,您只需发出如下查询:

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

这样你总是选择一个显示最少的项目,并在检索它后递增它。这应该(几乎)保证每次运行此代码时,都会得到一个新项目。