[英]Unique Random Record in Ruby
I have a Question table in which there is id# and title as columns. 我有一个问题表,其中有id#和标题作为列。 Now, I need to randomly select 5 questions from the table. 现在,我需要从表中随机选择5个问题。 I am seeing people are using: 我看到人们正在使用:
Question.order("RANDOM()").limit(5) //using postgre
Till now I have: 到现在为止我有:
def selectr
@randquestion=[]
while @randquestion.length<3 do
Question.uncached do
ques=Question.order("RANDOM()").first
@randquestion << ques
end
end
end
I found uncaching from Ruby on Rails Active Record RANDOM() always the same within a loop . 我发现从Ruby on Rails Active Record RANDOM()取消缓存在循环内始终是相同的 。
But I am not sure if this will give me unique questions. 但是我不确定这是否会给我带来独特的问题。 I want 3 unique questions only. 我只想要3个独特的问题。
You can do this by fetching each question via a separate SQL request, with subsequent requests excluding IDs for records already seen. 您可以通过一个单独的SQL请求获取每个问题,随后的请求不包括已经看到的记录的ID,即可实现此目的。 Here's an example, tested with Rails 5.2 and MySQL: 这是一个经过Rails 5.2和MySQL测试的示例:
def random_questions(number)
already_seen = []
number.times.map do
question = Question.order('RAND()').where.not(id: already_seen).first
already_seen << question.id
question
end
end
If you try this out with random_questions(3)
, you'll see: 如果使用random_questions(3)
尝试,您将看到:
Question Load (1.5ms) SELECT `questions`.* FROM `questions` WHERE 1=1 ORDER BY RAND() LIMIT 1
Question Load (1.4ms) SELECT `questions`.* FROM `questions` WHERE `questions`.`id` != 2 ORDER BY RAND() LIMIT 1
Question Load (1.3ms) SELECT `questions`.* FROM `questions` WHERE `questions`.`id` NOT IN (2, 1) ORDER BY RAND() LIMIT 1
As an aside, please note that order('RAND()')
triggers a deprecation warning in newer versions of Rails: order('RAND()')
一句,请注意order('RAND()')
在较新版本的Rails中会触发弃用警告:
DEPRECATION WARNING: Dangerous query method (method whose arguments are used as raw SQL) called with non-attribute argument(s): "RAND()". 优先警告:危险查询方法(其参数用作原始SQL的方法)以非属性参数“ RAND()”调用。 Non-attribute arguments will be disallowed in Rails 6.0. 在Rails 6.0中将禁止使用非属性参数。 This method should not be called with user-provided values, such as request parameters or model attributes. 不应使用用户提供的值(例如请求参数或模型属性)来调用此方法。 Known-safe values can be passed by wrapping them in Arel.sql(). 可以通过将已知安全值包装在Arel.sql()中来传递这些值。
To avoid this warning, use .order(Arel.sql('RAND()'))
instead. 为避免此警告,请改用.order(Arel.sql('RAND()'))
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.