Rails—get a random record from db?
You can try following database independent query:
User.find(User.pluck(:id).sample)
[DEBUG] (36.5ms) SELECT `users`.`id` FROM `users`
[DEBUG] User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 58229 LIMIT 1
this one fires two queries but this one is performance efficient as it took only 37ms to get single random user record.
whereas the following query will take around 624.7ms
User.order("RAND()").first
[DEBUG] User Load (624.7ms) SELECT `users`.* FROM `users` ORDER BY RAND() LIMIT 1
I have checked this for 105510 user records.
Random record in ActiveRecord
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.
Rails 3: Get Random Record
Thing.first(:order => "RANDOM()") # For MySQL :order => "RAND()", - thanx, @DanSingerman
# Rails 3
Thing.order("RANDOM()").first
or
Thing.first(:offset => rand(Thing.count))
# Rails 3
Thing.offset(rand(Thing.count)).first
Actually, in Rails 3 all examples will work. But using order RANDOM
is quite slow for big tables but more sql-style
UPD. You can use the following trick on an indexed column (PostgreSQL syntax):
select *
from my_table
where id >= trunc(
random() * (select max(id) from my_table) + 1
)
order by id
limit 1;
Rails select random record
In Rails 4 I would extend ActiveRecord::Relation
:
class ActiveRecord::Relation
def random
offset(rand(count))
end
end
This way you can use scopes:
SomeModel.all.random.first # Return one random record
SomeModel.some_scope.another_scope.random.first
Get random record
You can simply use .shuffle
on active record relation which will return you an array.
Post.where(available: 'true', approved: "true").shuffle.first
Or
Post.where(available: 'true', approved: "true").sample
Or more efficient way
Post.where(available: 'true', approved: "true").order("RANDOM()")
Selecting random record in rails
You'll need a separate spot to store the records being displayed already outside of your current process. The process might die or you will have multiple processes running (if it is meant for production purposes, that should definitely be the case).
As opposed to what tadman proposed I wouldn't recommend storing the sequence in the db as this will make adding new records more complicated.
Instead, I would add a simple displayed
(boolean) column (or separate table) and rely on what has been proposed in a different thread but flavored to your specific use case. So the query might be like this:
@qotd = Quote.where(displayed: false).order("RAND()").limit(1)
and of course a
@qotd.update_attribute :displayed, true
later on.
The displayed
column for all records will have to be reset if no candidate is found. All this, (query, update and reset) should probably happen within a single method.
What's the 'Rails 4 Way' of finding some number of random records?
You'll want to use the order
and limit
methods instead. You can get rid of the all
.
For PostgreSQL and SQLite:
User.order("RANDOM()").limit(10)
Or for MySQL:
User.order("RAND()").limit(10)
how to get a random record from the database in rails
Try this:
# Get 5 random users
@users = User.order('RAND()').limit(5)
Note that the RAND()
(MySQL) function is called RANDOM()
in PostgreSQL and SQLite.
Related Topics
How to Select Rows With Max(Column Value), Partition by Another Column in MySQL
Insert Text With Single Quotes in Postgresql
Calculate a Running Total in MySQL
Select Top 10 Records For Each Category
How to Use Case Statement in a Join Condition
How to Temporarily Disable a Foreign Key Constraint in MySQL
Difference Between Exists and in in Sql
How to Pass a Table Name into a Stored Proc
How to Limit the Number of Rows Returned by an Oracle Query After Ordering
How to Request a Random Row in Sql
Split Comma Separated Values to Columns in Oracle
Referring to a Column Alias in a Where Clause
Import CSV File into SQL Server