I am attempting to paginate a shuffled ActiveRecord query. The syntax for doing this using the Kaminari gem is:
@users = Kaminari.paginate_array(User.all.shuffle).page(params[:page]).per(20)
The issue with this is that User.all
is re-shuffled on each pagination request, causing duplicate records to be called. Is there any way to prevent this kind of duplication?
You need to pass seed for rand between queries
params[:seed] ||= Random.new_seed
srand params[:seed].to_i
@users = Kaminari.paginate_array(User.all.shuffle).page(params[:page]).per(20)
And in view add params[:seed] to all kaminari links to pages
As KandadaBoggu points out above, retrieving all of the User
records from the database is inefficient when you only need 20. I would suggest using MySQL's RAND()
function to perform the randomization before you return from the database. You can still pass a seed value to RAND()
to make sure the shuffling only happens once per session.
For example:
class User < ActiveRecord::Base
def self.randomized(seed = nil)
seed = seed.to_i rescue 0
order("RAND(#{seed})")
end
end
class UsersController < ApplicationController
before_filter :set_random_seed
def index
@users = User.randomized(session[:seed]).page(params[:page]).per(20)
end
private
def set_random_seed
session[:seed] ||= Random.new_seed
end
end
I don't have a MySQL installation to test against, but this should perform better than your original code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With