我有一个问题表,其中有id#和title作为列。 现在,我需要从表中随机选择5个问题。我看到人们正在使用:
def selectr
@randquestion=[]
while @randquestion.length<3 do
Question.uncached do
ques=Question.order("RANDOM()").first
@randquestion << ques
end
end
end
直到现在我有:
<div class='animation-box animate'>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
<div class="animation-bar"></div>
</div>
我发现从Ruby on Rails Active Record RANDOM() always the same within a loop进行了解除。
但我不确定这是否会给我带来独特的问题。我只想要3个独特的问题。
答案 0 :(得分:0)
您可以通过单独的SQL请求获取每个问题来执行此操作,后续请求不包括已经看到的记录的ID。这是一个用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
如果您使用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
顺便说一句,请注意order('RAND()')
会在较新版本的Rails中触发弃用警告:
DEPRECATION WARNING:使用非属性参数调用的危险查询方法(其参数用作原始SQL的方法):“RAND()”。 Rails 6.0中不允许使用非属性参数。不应使用用户提供的值调用此方法,例如请求参数或模型属性。可以通过将它们包装在Arel.sql()中来传递已知安全值。
要避免此警告,请改用.order(Arel.sql('RAND()'))
。