0

I have a system that produces literally thousands of reports in a single request to populate a table and I use kamanari to paginate 20 records per page. Because there could be thousands of reports being loaded in a single request, it sometimes takes several minutes for them to load, regardless of the request format is html or json. I tried a number of things with kaminari.

my_controller.rb
def my_table
  reports = unit.reports_for(history_date_range)  #This could return possibly 10,000 reports
  paginated_reports = reports.order('time desc').page(params[:page]).per(20)
  @reports = paginated_reports
  ...
end

my_table.html.haml
- @reports.each do |r|
  ...
= paginate @reports.page(params[:page]).per(20)

The problem with the above is that kaminari doesn't send only 20 records back to the view. It sends all 10,000, for example. And just paginates them in groups of 20. Even when I click the second page, it goes through the whole pagination route again, and queries 10,000 records and shows 20 records on the page.

Rather than this:

= paginate @reports.page(params[:page]).per(20)

I also tried this:

= paginate @reports, :total_pages => 2

And this still takes long but only shows 2 total pages, not all the pages that there are.

What I am trying to do is as follows. Let's say there are 100 records total and that means there are 50 pages in groups of 20. I only want to query the first 20, send it back to the view, and populate the view with those 20 records and have a little arrow sign indicating that there are more. Then when the user clicks that arrow sign, it then queries only the next set of 20 records, sends them back to view, and so forth. I don't want to have to be querying so many records at a single time and have the entire view populate with them.

JohnMerlino
  • 3,900
  • 4
  • 57
  • 89
  • Is there a question you would like to ask? – summea Mar 20 '13 at 16:16
  • @summea Yeah how do I get kaminari to only send 20 records back at a time, rather than sending them all back (in groups of 20) – JohnMerlino Mar 20 '13 at 16:18
  • You might want to have a look at this other [question/answer](http://stackoverflow.com/questions/10126316/fetch-objects-upon-pagination-rather-than-beforehand-rails-kaminari?rq=1)... – summea Mar 20 '13 at 16:26

1 Answers1

0

Below line is loading all data:

 reports = unit.reports_for(history_date_range)

After loading data you are using pagination which is similar to not using pagination in terms of performance and responsiveness. So you need to use pagination on this query. If you can give more details of what you are querying it will help to exact answer.

Rahul Tapali
  • 9,887
  • 7
  • 31
  • 44
  • I tried that already. Even if i get that to return 20 records, @reports.page(params[:page]).per(20), the per() method will override the limit(20) on unit.reports_for(history_date_range).limit(20). – JohnMerlino Mar 20 '13 at 16:35
  • The query looks like this: reports.where{(time > my{range.begin}) & (time < my{range.end})}. It selects report objects within a time range. I just want it to send 20 back at a time, but also to know which set of 20 to send back. – JohnMerlino Mar 20 '13 at 16:38
  • What is your model name ?? – Rahul Tapali Mar 20 '13 at 16:39
  • a model called Unit and a model called Report. a unit has many reports. – JohnMerlino Mar 20 '13 at 16:39
  • Can you post the sql query which doing things? Because I am not getting what exactly you are doing – Rahul Tapali Mar 20 '13 at 16:43
  • Report Load (854.7ms) SELECT "reports".* FROM "reports" WHERE "reports"."unit_id" = 6515 AND (("reports"."time" > '2013-03-20 04:00:00.000000' AND "reports"."time" < '2013-03-21 03:59:59.999999')) THe user selects a time range. So it could be a large time range, meaning more reports. – JohnMerlino Mar 20 '13 at 16:44
  • `Report.where("unit_id = ? and time > ? and time < ?",unit_id, time1, time2).page(params[:page]).per(20)` – Rahul Tapali Mar 20 '13 at 16:51