Ruby on rails 获取优先于尚未选择的记录的随机记录

Ruby on rails 获取优先于尚未选择的记录的随机记录,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我试图找到一种不重复地获取一些随机记录的方法,至少直到我一次性从表中获取所有记录为止 我有一张有一些问题的桌子(3000) 我创建了一个测验,选择一些随机问题(30)。我需要创建一个包含所有问题的测验,所以在我使用所有3000个问题之前,不要重复。然后我可以开始向我们提问另一个周期的问题 在单用户环境中,每次使用问题时,我都可以在问题表中添加一个字段“count”来增加,但我有一个多用户环境,所以我不能污染问题表 有什么想法吗?如果您不想添加任何数据库字段,最好的方法是使用redis 1-在re

我试图找到一种不重复地获取一些随机记录的方法,至少直到我一次性从表中获取所有记录为止

我有一张有一些问题的桌子(3000)

我创建了一个测验,选择一些随机问题(30)。我需要创建一个包含所有问题的测验,所以在我使用所有3000个问题之前,不要重复。然后我可以开始向我们提问另一个周期的问题

在单用户环境中,每次使用问题时,我都可以在问题表中添加一个字段“count”来增加,但我有一个多用户环境,所以我不能污染问题表


有什么想法吗?

如果您不想添加任何数据库字段,最好的方法是使用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

如果不想添加任何数据库字段,最好的方法是使用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

我认为您可以使用缓存来存储已排序的未使用问题的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)

现在您可以使用
quick\u questions=Question.find(quick\u questions\u id)
查找您的问题。我认为您可以使用缓存来存储排序后的未使用问题的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)

现在,您可以使用
quick\u questions=Question.find(quick\u questions\u id)
查找您的问题。您必须创建一个中间表

假设您的模型是
用户
问题

rails g migration create_users_questions user_id:integer question_id:integer
rake db:migrate
这将在数据库中生成一个
users\u questions

然后,在
user.rb中:

has_and_belongs_to_many :questions
has_and_belongs_to_many :users
在你的
问题中.rb

has_and_belongs_to_many :questions
has_and_belongs_to_many :users
新表的每一行将包含一个
用户id
和一个
问题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

然后再次添加…

必须创建一个中间表

假设您的模型是
用户
问题

rails g migration create_users_questions user_id:integer question_id:integer
rake db:migrate
这将在数据库中生成一个
users\u questions

然后,在
user.rb中:

has_and_belongs_to_many :questions
has_and_belongs_to_many :users
在你的
问题中.rb

has_and_belongs_to_many :questions
has_and_belongs_to_many :users
新表的每一行将包含一个
用户id
和一个
问题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

然后再次添加…

您需要添加另一个模型来跟踪用户与特定问题的交互

用户问题:

  • 属于:用户
  • 属于:问题
  • 已使用(布尔值)
用户:

  • 有很多:用户问题
  • 有很多:问题,通过::用户问题
然后需要运行一个有限的随机查询:

user\u question=user.user\u questions.where(使用:false).order(“RANDOM()”).first

这将为您提供下一个要使用的问题。一旦回答完毕,你会将其标记为已使用,这样就不会再次拾取


重新生成测验时,需要重置为false。或者,您可以使用计数。。。但是,如果您上次的测验没有使用所有的问题,您将需要以某种方式重置,否则您的计数将被关闭。

您将需要添加另一个模型来跟踪用户与特定问题的交互

用户问题:

  • 属于:用户
  • 属于:问题
  • 已使用(布尔值)
用户:

  • 有很多:用户问题
  • 有很多:问题,通过::用户问题
然后需要运行一个有限的随机查询:

user\u question=user.user\u questions.where(使用:false).order(“RANDOM()”).first

这将为您提供下一个要使用的问题。一旦回答完毕,你会将其标记为已使用,这样就不会再次拾取


重新生成测验时,需要重置为false。或者,您可以使用计数。。。但是,如果您上次的测验没有使用所有的问题,您将需要以某种方式重置,否则您的计数将被取消。

只有一件事。注意这个:
Question.where.not(id:@user.Question\u id)
。UPD:嗯,这个问题似乎很老了,这是Rails 4的
而不是
语法。@D-side,这行得通吗<代码>:id
表示整数,而
@user。问题\u id
是一个数组。比那稍微复杂一点
question\u id
是从数据库中选择整数的关系。
where
-条件中的关系在(子查询)
中解释为
(为
where.NOT
添加了
NOT
)。因此,实际上,这甚至是一个单一的查询,如
选择问题。*其中id不在(SELECT questions.id)
允许我不同意<代码>问题ID实际上是一个数组。(您可以确认您是否在控制台中运行类似于
@user.question\u ids.class
的程序。为了确认它确实有效,我已经对它进行了测试。因此,我将更新我的答案,谢谢。那么我是如何得到子查询的。我将检查它。也许某个版本的Rails是相关的。请注意:
question.where.not(id:@user.question\u id)
.UPD:嗯,这个问题似乎很老了,这是Rails 4的
而不是
语法。@D-side,这行吗?
:id
表示整数,而
@user。question\u id
是一个数组,它会。它比这个稍微复杂。
question\id
是一个关系,它从数据库中选择
的整数e、 关系