Categories
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
    end
    
    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)
    else
      return features_arr
    end
  end

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 almosteffortless.com 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?
  end

  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)
    else
      return features_arr
    end
  end

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.