I am displaying a list of articles and using will_paginate gem and endless scrolling. This is all working fine.
My problem, however, is that I am occasionally getting multiple copies of the same article in the view. It doesn't happen all the time, and nor with every article, but enough that it is bloody annoying.
I know there is no duplication in the database, and so the problem occurs in the rendering somehow.
Here is my controller:
@articles = Article.order("date_published DESC", "RANDOM()").paginate(:page => params[:page],:per_page => 10)
I am trying somehow to include the distinct or uniq method, but it seems I can't use either with the order method.
I am using pg for db.
Any help would be greatly appreciated!
The issue arises with your sub-sort, RANDOM()
.
Imagine I have these posts:
id published title
----------------------
1 1/1/1970 One
2 1/2/1970 Two
3 1/2/1970 Three
4 1/3/1970 Four
If I request page one (with a page size of 2), I can either get 4 and 3, or 4 and 2. Now, if I request page 2 I can either get 3 and 1 or 2 and 1. This is because of the RANDOM()
sub-sort. The first query may pull the page from this result:
id published title
----------------------
4 1/3/1970 Four
3 1/2/1970 Three
2 1/2/1970 Two
1 1/1/1970 One
Which is 4 and 3, but this result is also possible:
id published title
----------------------
4 1/3/1970 Four
2 1/2/1970 Two
3 1/2/1970 Three
1 1/1/1970 One
Which is 4 and 2. And either of these results will also result in a different page 2 as well. This random sort is the cause of your duplicates, you need to use consistent sorts or manage removal of duplicates in some other way. Such as:
@articles = Article.where.not(id: list_of_already_fetched_ids).order("date_published DESC", "RANDOM()").paginate(:page => params[:page],:per_page => 10)
NOTE: where.not
is usable in Rails 4, if you are not using Rails 4 you'll need to find another way to implement that filter.