Trevor Turk

A chess-playing machine of the late 18th century, promoted as an automaton but later proved a hoax.

Random Records in Rails

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:
  1. Select a Record by Random Offset
  2. Randomize with the Database
  3. Randomize with Ruby
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:
class Widget < ActiveRecord::Base
  
  # ...
  
  def self.random
    ids = connection.select_all("SELECT id FROM widgets")
    find(ids[rand(ids.length)]["id"].to_i) unless ids.blank?
  end
  
end
Then, you can use the following bit of code in a controller like so:
class SomeController < ApplicationController
  
  # ...

  def some_action
    @widget = Widget.random
  end

end
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:

« Home page