Random record in ActiveRecord
Rails 6
As stated by Jason in the comments, in Rails 6, non-attribute arguments are not allowed. You must wrap the value in an Arel.sql()
statement.
Model.order(Arel.sql('RANDOM()')).first
Rails 5, 4
In Rails 4 and 5, using Postgresql or SQLite, using RANDOM()
:
Model.order('RANDOM()').first
Presumably the same would work for MySQL with RAND()
Model.order('RAND()').first
This is about 2.5 times faster than the approach in the accepted answer.
Caveat: This is slow for large datasets with millions of records, so you might want to add a limit
clause.
Your example code will start to behave inaccurately once records are deleted (it will unfairly favor items with lower ids)
You're probably better off using the random methods within your database. These vary depending on which DB you're using, but :order => "RAND()" works for mysql and :order => "RANDOM()" works for postgres
Model.first(:order => "RANDOM()") # postgres example
I haven't found an ideal way to do this without at least two queries.
The following uses a randomly generated number (up to the current record count) as an offset.
offset = rand(Model.count)
# Rails 4
rand_record = Model.offset(offset).first
# Rails 3
rand_record = Model.first(:offset => offset)
To be honest, I've just been using ORDER BY RAND() or RANDOM() (depending on the database). It's not a performance issue if you don't have a performance issue.