Rand() order and Pagination


#1

I’m stumped with how to combine pagination and a rand order_by from my
model.

Let’s say I am a teacher and have a table full of test questions. I want
to
return a query of 20 questions and use the paginator to return 1 or 5 or
10
per page. The catch is I want the 20 question to be random and in random
order so they don’t keep getting the first 20 questions.

On each paginated page, the paginator performs a new query using a limit
X
and an offset X to return different sequential results. If I use
order_by
rand() in my query then I will get a random result, but there is a
chance I
will get a duplicate question.

Does anyone have any suggestions on how to return random results with
pagination?

Thanks,

Steve


#2

One way to tackle this would be to select randomly into a temporary
table,
then paginate that table.

–another steve


#3

steve.odom wrote:

I’m stumped with how to combine pagination and a rand order_by from my
model.

Let’s say I am a teacher and have a table full of test questions. I want
to
return a query of 20 questions and use the paginator to return 1 or 5 or
10
per page. The catch is I want the 20 question to be random and in random
order so they don’t keep getting the first 20 questions.

On each paginated page, the paginator performs a new query using a limit
X
and an offset X to return different sequential results. If I use
order_by
rand() in my query then I will get a random result, but there is a
chance I
will get a duplicate question.

Does anyone have any suggestions on how to return random results with
pagination?

Thanks,

Steve

This should do it:

in application.rb:

def paginate_collection(collection, options = {})
default_options = {:per_page => 10, :page => 1}
options = default_options.merge options

 pages = Paginator.new self, collection.size, options[:per_page], 

options[:page]
first = pages.current.offset
last = [first + options[:per_page], collection.size].min
slice = collection[first…last]
return [pages, slice]
end

in your controller:

@question_pages, @questions = paginate_collection Question.find(:all,
:order => “rand()”), :page => @params[:page]

–Jonathan


#4

This worked great. Thanks!


#5

Thanks to both of you for the suggestions. I’m going to have to work
through
Jonathan’s suggestion - I don’t quite grasp it at first glance. I’m
using a
temp table solution to do something else, so that approach is a
possiblity.

Steve


#6

Jonathan,

Wouldn’t this give you a new randomized list on every page? ie. when
you’re
on page one, you get a the first set of 10 random questions, then on
page 2
rand() is called again and you get another 10 random numbers which may
include questions that were displayed on the first page.

Am I missing something?

Thanks

Hammed