Clean way to find ActiveRecord objects by id in the order specified

It’s not that MySQL and other DBs sort things on their own, it’s that they don’t sort them. When you call Model.find([5, 2, 3]), the SQL generated is something like:

SELECT * FROM models WHERE models.id IN (5, 2, 3)

This doesn’t specify an order, just the set of records you want returned. It turns out that generally MySQL will return the database rows in 'id' order, but there’s no guarantee of this.

The only way to get the database to return records in a guaranteed order is to add an order clause. If your records will always be returned in a particular order, then you can add a sort column to the db and do Model.find([5, 2, 3], :order => 'sort_column'). If this isn’t the case, you’ll have to do the sorting in code:

ids = [5, 2, 3]
records = Model.find(ids)
sorted_records = ids.collect {|id| records.detect {|x| x.id == id}} 

Leave a Comment