There are a number of different ways to retrieve random items from a database in Rails, most of which have been discussed at length on the Rails wiki. According to this article, there are 3 preferred methods:
For an in-depth look into these options, you can peruse this discussion page, which details some of the pros and cons of different strategies for randomization.
After trying out a few of the techniques that abound in this area, I stumbled across an article from Jamis Buck, where he discusses a RESTful way to approach the creation of custom finders. Although randomization isn't the focus of the article, he does provide a bit of guidance in that regard. His strategy uses Ruby for the randomization, and employs 2 light-weight queries. The first query gathers a list of valid ids. The second simply selects a single item using that (randomized) id.
So, I did a bit of cargo-culting and repurposing to achieve an efficient, database agnostic way to retrieve random items from a database using ActiveRecord. Simply add the following to the model from which you'd like to be able to pull random records:
- Select a Record by Random Offset
- Randomize with the Database
- Randomize with Ruby
class Widget < ActiveRecord::Base
ids = connection.select_all("SELECT id FROM widgets")
find(ids[rand(ids.length)]["id"].to_i) unless ids.blank?
Then, you can use the following bit of code in a controller like so:
class SomeController < ApplicationController
@widget = Widget.random
And you've got a small and efficient "random finder" for use throughout your app. Lovely.
Update I just came across a comment from Rails Core member Koz that provides an alternative that seems compelling at fist glance: