asoftware's avatar

Random Order a Collection With Pagination

I have a collection of 50 items (model = Books) and I would like to return them uniquely 10 per page (paginated) but in a random order. I tried using Book::inRandomOrder()->paginate(10), but when I go to page 2, 3, etc... I see books that were already shown on page 1 or some previous page.

I did a workaround with adding a randomValue column to the table and then doing orderBy(“randomValue”)->paginate(10), but that seems like a hack way to do it.

What’s the better way to do this?

0 likes
11 replies
asoftware's avatar

Oh wow... I’ll give that a try. Don’t know how I missed that.

asoftware's avatar

@michaloravec

I tried this and I am still receiving duplicate items on page 2, 3, etc....

$books = Book::where('review_id', $review->id)->inRandomOrder('foobar')->paginate(10);

Its like when you click the pagination link... ?page=2.... ?page=3 on that collection, it goes out and gets 10 new items and doesn't hold state of what it already displayed.

jlrdw's avatar

Is it correct if you just order by (whatever field).

asoftware's avatar

@jlrdw

That's what I am doing now as my workaround ... but it just felt weird to put a column in the table to hold a random value and then orderBy that instead of using something built into the Laravel eloquent methods. I literally just want to randomly get a collections of books... then only display 10 at a time and let them page through them... but not show ones that were shown on other pages.

jlrdw's avatar

There can be collisions with random. I usually have an array in random order of (whatever), and as I use one unset from array.

So:

1,2,3,4,5,6,7,8,9,10,11,12,13,14 etc

just example, get one at a time randomly up to the number you need.

Like 3 then 9, then 14 is fetched randomly.

As you get each unset those.

Always worked for me.

Edit: also and just fyi, when you said:

instead of using something built into the Laravel eloquent methods

Taylor is using:

RAND(seed)

From MySql or newid if Sql Server.

So try it in phpmyadmin and see if you get collisions, if not, there could be a "bug" in inRandomOrder.

Just an observation.

MichalOravec's avatar

Add there a number like 1 then it works in mysql.

$books = Book::inRandomOrder('1')->paginate(10);

Which database do you use?

asoftware's avatar

Sorry, that was a copy and paste error. It should have been this...

$books = Book::where('name', 'like', '%' . $search . '%')->inRandomOrder('foobar')->paginate(10);

I'm using SQLite as my database.

Please or to participate in this conversation.