我试图找到一种方法来获取一些随机记录而不重复,至少在我从表中获取所有记录一次之前。
我有一些问题(3000)。
我创建一个测验选择一些随机问题(30)。我需要用所有问题创建测验,所以不用重复,直到我使用所有3000个问题。然后我可以开始向我们提出另一个循环的问题。
在单个用户环境中,我可以添加一个字段" count"每次我使用问题时都会在我的问题表中增加,但我有一个多用户环境,所以我不能污染问题表。
有什么想法吗?
答案 0 :(得分:3)
您必须创建一个中间表。
假设您的模型为User
和Question
:
rails g migration create_users_questions user_id:integer question_id:integer
rake db:migrate
这将在您的数据库中生成users_questions
表。
然后,在user.rb
:
has_and_belongs_to_many :questions
和您的question.rb
:
has_and_belongs_to_many :users
新表格的每一行都包含user_id
和question_id
因此,要为用户@user
提供未使用的问题:
通用语法
@unused_questions = Question.where('id not in (?)',@user.questions.map(&:id))
Rails~> 4.0语法 [感谢D-Side]
@unused_questions = Question.where.not(id:@user.question_ids)
并向@user添加一个新的,用过的问题(让@question说出来)
@user.questions<<@question
那是故事的结尾......
最后,要重置@用户问题的状态:
if @unused_questions.empty? # we have defined that above
@user.questions.clear
end
然后再次添加......
答案 1 :(得分:0)
如果您不想添加任何数据库字段,最好的方法是使用redis
1-在redis中添加所有问题ID
$redis.sadd 'set_one', Question.pluck(:id)
2-点击选择随机id的方法并将其从列表中删除
def get_rand_question
random_id = $redis.spop "set_one"
Question.find random_id
end
答案 2 :(得分:0)
我认为您可以使用缓存来存储已排序的未使用问题的商店ID。
available_question_ids = Rails.cache.read('available_question_ids')
if available_questions_ids.nil? || available_question_ids.empty?
available_question_ids = Question.pluck(:id).to_a.shuffle
end
quiz_questions_ids = available_question_ids.pop(30)
Rails.cache.write('available_question_ids', available_question_ids)
现在,您可以使用quiz_questions = Question.find(quiz_questions_ids)
找到您的问题。
答案 3 :(得分:0)
您需要添加其他模型来跟踪用户与特定问题的互动。
用户问题:
用户:
然后,您将需要运行有限的随机查询:
user_question = User.user_questions.where(used:false).order(“RANDOM()”)。first
这将为您提供下一个要使用的问题。一旦它被回答,你会将它标记为已使用,因此它不会被再次拾取。
重新生成测验时,您需要重置为false。或者你可以使用计数......但是如果你的上一次测验没有使用所有问题,你需要以某种方式重置,否则你的计数将被取消。