I’m trying to figure out how to make a scope that will return random ActiveRecords while also supporting will_paginate.
Right now each page view gets a completely different random set of ActiveRecords. Thus each pagination link, is actually just another random set of records.
How might I set up a scope so that it will be a random order that persists through pagination?
I’m guessing that I need to have some sort of seed that is based on time?
I’m guessing that you’re using
ORDER BY RAND()in your SQL to get your random ordering. If you are, then you can provide a seed for the random number generator:So you just need to pick a seed (possibly even by using
seed = rand(1e6)or something similar in your Ruby code) and track that seed in the session. Then, for the next page, pull the seed out of the session and feed it to MySQL’sRANDfunction.Keep in mind that
ORDER BY RAND()(with or without a seed) isn’t the cheapest operation on the planet. If your searchable table is small, you could generate a table with a bunch of columns, fill it with random numbers (probably generated byRAND), and join that table in to provide your random sequence to order by. You would provide different sequences to different viewers by choosing different columns from the random number table: for one user you sort by column 11 of the random number table/matrix but another user will use column 23. Keep in mind that tables (with a primary key) really are just functions on a finite domain (and vice versa) so which you choose is often just an implementation detail. ImplementingRANDusing a table will usually be pretty cumbersome but I thought I’d mention the option anyway.