Random record in ActiveRecord

2019-01-02 19:55发布

I'm in need of getting a random record from a table via ActiveRecord. I've followed the example from Jamis Buck from 2006.

However, I've also come across another way via a Google search (can't attribute with a link due to new user restrictions):

 rand_id = rand(Model.count)
 rand_record = Model.first(:conditions => ["id >= ?", rand_id])

I'm curious how others on here have done it or if anyone knows what way would be more efficient.

22条回答
琉璃瓶的回忆
2楼-- · 2019-01-02 20:09

You can use the Array method sample, the method sample returns a random object from an array, in order to use it you just need to exec in a simple ActiveRecord query that return a collection, for example:

User.all.sample

will return something like this:

#<User id: 25, name: "John Doe", email: "admin@example.info", created_at: "2018-04-16 19:31:12", updated_at: "2018-04-16 19:31:12">
查看更多
琉璃瓶的回忆
3楼-- · 2019-01-02 20:09

For MySQL database try: Model.order("RAND()").first

查看更多
孤独寂梦人
4楼-- · 2019-01-02 20:10

Rails 4.2 and Oracle:

For oracle you can set a scope on your Model like so:

scope :random_order, -> {order('DBMS_RANDOM.RANDOM')}

or

scope :random_order, -> {order('DBMS_RANDOM.VALUE')}

And then for a sample call it like this:

Model.random_order.take(10)

or

Model.random_order.limit(5)

of course you could also place an order without a scope like so:

Model.all.order('DBMS_RANDOM.RANDOM') # or DBMS_RANDOM.VALUE respectively
查看更多
后来的你喜欢了谁
5楼-- · 2019-01-02 20:15

I made a rails 3 gem to handle this:

https://github.com/spilliton/randumb

It allows you do do stuff like this:

Model.where(:column => "value").random(10)
查看更多
春风洒进眼中
6楼-- · 2019-01-02 20:15

What about to do:

rand_record = Model.find(Model.pluck(:id).sample)

For me is much clear

查看更多
十年一品温如言
7楼-- · 2019-01-02 20:17

It doesn't have to be that hard.

ids = Model.pluck(:id)
random_model = Model.find(ids.sample)

pluck returns an array of all the id's in the table. The sample method on the array, returns a random id from the array.

This should perform well, with equal probability of selection and support for tables with deleted rows. You can even mix it with constraints.

User.where(favorite_day: "Friday").pluck(:id)

And thereby pick a random user who likes fridays rather than just any user.

查看更多
登录 后发表回答