Ask A Question

Notifications

You’re not receiving notifications from this thread.

Using will_paginate and .limit(x) together.

Simon P asked in Rails

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

Reply

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?

Reply

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.

Reply

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?

Reply

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

Reply

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. 👍

Reply

Thanks Chris

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

Much appreciated,

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,329+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.