I have a Rails engine that defines a class method top(count)
on a model of choice. What this method does is grab count
IDs from a sorted set (ZSET) in Redis. The idea is that each item of this model has a score, and this method is to return the "best" records. The method essentially looks like this:
def self.top(count = 1)
ids = redis.zrevrange(self.score_set, 0, count - 1)
items = self.find ids
if count == 1
return items.first
else
return items.sort { |x, y| ids.index(x.id) <=> ids.index(y.id) }
end
end
As you can see, I currently sort the records after the fact because databases (or the adapters) tend not to maintain order when finding by multiple IDs. For instance, Model.where('ID IN (?)', ids)
will sort by ascending IDs rather than the order of the passed IDs.
Sorting the items returns an Array
, but I'd like this method to return an ActiveRecord::Relation
instead so that my users can chain it with other ActiveRecord query methods. Is there a way I can use the built-in ActiveRecord query methods to maintain order from my array of IDs? Or alternatively, is there a way to construct an ActiveRecord::Relation
from an array of records?