Rails控制器 - 随机记录

时间:2013-06-07 23:32:02

标签: ruby-on-rails

简单的问题,此代码是否会确保rand()调用不会连续两次返回相同的记录?

似乎来自点击测试,但我真的不自信。

def thoughts  
  last_thought = 0 if last_thought == nil #this is the part that seems wrong for my goal
  th = Array.new

  Thought.all.each do |t|
    th << t.id
  end

  th.pop(last_thought)
  @rand_thought = Thought.find(rand(th.first..th.last))
  last_thought = @rand_thought.id
end

根据@ user198201的建议,我已将代码修改为:

def thoughts
  shuffle_thought ||= Thought.all.shuffle
  @rand_thought = shuffle_thought.pop
  @rand_thought
end

然后测试,我添加了这个方法:

def thinker
  a = Array.new
  20.times do
    a << thoughts.id
  end
  a
end

以下是我现在在Rails控制台中获得的内容:

t = ThoughtController.new

=&GT; #&LT;'ThoughtController:0x007f95636ae000&GT;

t.thought.id

Thought Load (0.4ms)  SELECT "thoughts".* FROM "thoughts"

=&GT; 7

t.thinker

Thought Load (0.4ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.4ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.3ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"
Thought Load (0.2ms)  SELECT "thoughts".* FROM "thoughts"

=&GT; [5,9,4,7,4,5,8,7,7,1,6,1,8,6,4,1,2,7,3,2]

在阵列中间就是重复。我仍然在寻找代码以避免连续两次获得相同的记录。

1 个答案:

答案 0 :(得分:1)

由于您正在加载所有想法,因此不清楚为什么要返回数据库来获取随机想法。

def random_thought
  @thoughts ||= Thought.all.shuffle
  @thoughts.pop
end

请注意,@thoughts将所有想法存储到一个实例变量中,该变量在下次调用random_thought时应该仍然存在,无论如何在当前请求中,而random_thoughts || =将无法工作,因为它将思想存储在本地变量。这意味着每当你要求随机思考时它就会消失,这会导致每次加载所有想法,这是你的日志输出所暗示的,从而增加了你重复的机会,以及可怜的低效率。如果所有的想法都存储在@thoughts和shuffled中,那么在你弹出所有的@thoughts之前,你肯定永远不会跑。

Alex D是正确的:效率。为了您的实验,可以加载所有的想法;如果这是一个生产现场,那将是一场灾难。有关一些想法,请查看SQL Antipatterns一书,在这里的幻灯片中总结:http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back

向前跳到幻灯片148.您基本上想要查询最大ID,根据随机数选择一个ID,然后获取下一个最高的现有记录。