Skip to main content

Using will_paginate and .limit(x) together.

Rails • Asked by Simon P


Hi

It appears that will_paginate and .limit(x) will not work together. So this didn't work:

(I am trying to get 150 most recent records and paginate them)

@articles = Article.where.not(site_id: 'HIDE')
.limit(150)
.order('articles.created_at DESC')
.paginate(:page => params[:page], :per_page => 30)

But this does work:

(using the total_entries method of will_paginate)

@articles = Article.where.not(site_id: 'HIDE')
.order('articles.created_at DESC')
.paginate(:page => params[:page], :per_page => 30,total_entries: 150)

BUT @articles still pulls all 4500 records which isnt very efficient and also @articles.count returns 4500 rather than 150.

Is there away I can just get the 150 records from the DB and paginate them?

Thanks to craftycanuck in the Slack channel for helping me get this far,

Simon

Gravatar Chris Oliver commented on : Mod Staff

Hey Simon,

One super important thing here is that pagination uses both limit and order to make pages. When you add limit in on top of that, you're going to likely break pagination because of that.

Are you trying to limit the number of pages displayed?

Thanks Chris

I want the 150 most recent Articles paginated in 5 pages of 30.

I have managed a workaround but would love to understand how I could accomplish the original problem.

Gravatar Chris Oliver commented on : Mod Staff

You're definitely doing something that is outside the scope of most pagination gems. What I would probably do is customize the view template to only show the last 5 pages links. This would visually make it so you could only see the first X items and then you can have your controller also verify the page # is between 1 and 5 so the users can't go outside those boundaries.

What does your solution look like right now?

Hi Chris

Thanks for your continued input.

My problem was that I wanted to display "Here are the last 150 articles" but the view has other options when it might show less or more articles so 150 was populated by @articles.count. The problem is when you use @articles.count on a paginated active record set it returns the whole table count rather than the number you limited the pagination set to.

My work around was to create a method called getarticlecount.

Which does this:

def getarticlecount(view)
    if view == "150"
      return "150"
    else
      return @articles.count
    end
  end

Made accessible to the view by adding this in the controller:

helper_method :getarticlecount

Rendered in the view by this:

<%= pluralize(getarticlecount(params[:view]), "result") %>

Not sure if the breaks any rails or ruby best practises but it does the job! Open to refactoring.

Simon

Gravatar Chris Oliver commented on : Mod Staff

That works. The other thing you can do is look at @articles.total_entries I believe with will_paginate which will give you the count of all the results, not just the current page. It's either that or total_count on that or Kaminari.

Your solution is simple enough though so I would stick with that. 👍

Thanks Chris

I did have a play with total_count but couldnt quite get it right.

Much appreciated,

Login or create an account to join the conversation.