October 07, 2006
Older: Overtaken By Fake Comments
Newer: Rails Gets Unicode Handling
Active Record Find Tip
Jamis Buck has come roaring back into blogging since his switch to Mephisto. Yesterday, he released another nice tip on Helping ActiveRecord finders help you. He wanted to have a way to display a random record from the database. At first, he was going to create a new action, but knowing that the action would function primarily the same as show, he thought it better to extend the find method in Active Record like so:
class Thing < ActiveRecord::Base
def self.find(*args)
if args.first.to_s == "random"
ids = connection.select_all("SELECT id FROM things")
super(ids[rand(ids.length)]["id"].to_i)
else
super
end
end
end
Now he could call Thing.find(‘random’) to get a random record from the database. This means his show action can display a random record simply by hitting the thing/random
restful route (where random would be passed in as the id). You can read the full article on his blog.
6 Comments
Dec 12, 2006
Might want to check out alias_method_chain:
class Thing < ActiveRecord::Base class << self def find_with_random(*args) if args.first.to_s == "random" ids = connection.select_all("SELECT id FROM things") find_without_random(ids[rand(ids.length)]["id"].to_i) else find_without_random(*args) end end alias_method_chain :find, :random end end
Dec 12, 2006
Wow, that was awful. Sorry about the lack of line breaks; left out a <pre>.
Better?
Feb 02, 2007
Its a little more verbose, but wouldn’t this suffice?
Thing.find(:first, :order => “rand()”)
Feb 03, 2008
This is quite concise but unfortunately it is not database independent. It is rand() in MySQL and random() in PostgreSQL, for example.
Feb 20, 2008
I don’t like any of these solutions.
I think what you want is simply:
Thing.find :first, :offset => rand(Thing.count)
Aug 08, 2008
Very good article! Ruby forever :)
Sorry, comments are closed for this article to ease the burden of pruning spam.