blog Code learning rails

Ruby on Rails: Get some random records

EDIT AGAIN: Much better..

To get a ‘num_reqd’ array of random objects, you can use something like this.

  named_scope :large, :conditions => ['image_file_name IS NOT ?', nil]
  named_scope :small, :conditions => ['small_image_file_name IS NOT ?', nil] 

  def self.get(num_reqd,features_arr=[],size="large")
    if size=="small"
      collection = Feature.small
    elsif size=="large"
      collection = Feature.large
    return collection if collection.size <= num_reqd

    # num_reqd.times{feature=self.random(collection); features_arr.push(feature) unless features_arr.include?(feature)}
    features_arr = collection.find(:all, :limit => num_reqd, :order => 'rand()')

    if features_arr.size < num_reqd
      return Feature.get(num_reqd, features_arr, size)
      return features_arr

EDIT: It's much cleaner and easier to use something in the form below, though the following is probably useful in some cases and is possibly interesting as a code snippet.

User.find(:all, :order => 'rand()')

---- end edit.

Working from a baseline of the code found here at I've extended a 'random record grabber' to get a specific number of unique records from a Rails data table.

Basically - the random method makes a database call to get the ids of a table, and sends back a random entry. self.get is a recursive method which provides a 'total number required' and a base array to start from (if you wish to specify entries to appear in the otherwise 'random' list). First year computer science should help get your head around the rest!

def self.random
    ids = connection.select_all("SELECT id FROM features")
    find(ids[rand(ids.length)]["id"].to_i) unless ids.blank?

  def self.get(num_reqd,features_arr=[])
    num_reqd.times{feature=self.random; features_arr.push(feature) unless features_arr.include?(feature)}

    if features_arr.size < num_reqd
      return Feature.get(num_reqd, features_arr)
      return features_arr

Be aware, there is more efficiency to be found in the database call (i.e. it should be cached). Also, you'll want to be sure there are at least 'num_reqd' items in the database.