Rails - 如何从对象中获取随机记录?

时间:2015-03-04 12:01:05

标签: mysql ruby-on-rails ruby arrays random

我正在做这样的事情:

data = Model.where('something="something"')
random_data = data.rand(100..200)

返回:

NoMethodError (private method `rand' called for #<User::ActiveRecord_Relation:0x007fbab27d7ea8>):

一旦我得到这个随机数据,我需要遍历这些数据,如下所示:

random_data.each do |rd|
  ...

我知道有一种方法可以在MySQL中获取随机数据,但是我需要选择400次随机数据,所以我认为从数据库中加载一次数据400次以选择随机数比在MySQL上运行查询400次。

但是 - 如何摆脱这个错误?

NoMethodError (private method `rand' called for #<User::ActiveRecord_Relation:0x007fbab27d7ea8>):

提前谢谢

4 个答案:

答案 0 :(得分:2)

我会将以下范围添加到模型中(取决于您使用的数据库):

# to model/model.rb
# 'RANDOM' works with postgresql and sqlite, whereas mysql uses 'RAND'
scope :random, -> { order('RAND()') } 

然后,以下查询将在一个查询中加载对象的随机数(范围为200-400):

Model.random.limit(rand(200...400))

如果你真的想在Rails中而不是在数据库中这样做,那么加载所有记录并使用sample

Model.all.sample(rand(200..400))

但这要慢一些(取决于数据库中的条目数),因为Rails会从数据库加载所有记录并将它们实例化为可能占用大量内存的内容。

答案 1 :(得分:0)

使用data.sample(rand(100..200)) 有关rand无法正常工作的更多信息,请阅读https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4555

答案 2 :(得分:0)

另一种不是DB特定的方式是:

def self.random_record
  self.where('something = ? and id = ?', "something", rand(self.count))
end

这里唯一的事情是 - 正在执行2个查询self.count正在执行一个查询 - SELECT COUNT(*) FROM models,另一个是您获取随机记录的实际查询。

好吧,现在假设您想要n个随机记录。然后把它写成:

def self.random_records n
  records = self.count
  rand_ids = Array.new(n) { rand(records) }
  self.where('something = ? and id IN (?)', 
             "something", rand_ids )
end

答案 3 :(得分:0)

这实际上取决于你想要多少努力来优化它,因为有多个解决方案。这是2个选项..

简单的方法是使用ORDER BY RAND() LIMIT 400随机选择400项。

或者,只需选择月球下的所有内容,然后使用Ruby随机选择总结果集中的400,例如:

data = Model.where(something: 'something').all # all is necessary to exec query
400.times do
  data.sample # returns a random model
end

我不推荐第二种方法,但它应该可行。