Ruport and WillPaginate

28 views
Skip to first unread message

Tygo

unread,
Sep 23, 2009, 3:14:47 AM9/23/09
to Ruby Reports
Hello all,
I'm trying to use ruport and pagination and right now I do the
following:

table = model.report_table(:all, :only => columns, :conditions =>
filters, :offset => current_offset)

n_records = table.size
per_page = 20

# add page offset to get correct values.
current_page = 1
if(params["page"] != nil)
current_page = params["page"].to_i
end

# paginate records.
@records = WillPaginate::Collection.create(current_page, per_page,
n_records) do |pager|
start = (current_page-1)*per_page # assuming current_page is 1
based.
pager.replace(@records.to_a[start, per_page])
end

As you can see in the code this fetchs all records because I need to
know the number of records and pass that information to the paginator.
I want to avoid doing this (because I have a lot of records in the
database) and fetch only the 20 records that will be showed. Can
anyone help me?

Thanks.
Best regards,
Tygo

Sylvain Abélard

unread,
Sep 23, 2009, 3:40:22 AM9/23/09
to ruby-r...@googlegroups.com
Hi Tygo,

WillPaginate does what you want by default, no need for additional steps.
It has two options you could use :

:total_entries
Instead of loading, counting, then discarding all but the 20 elements
you want, you can do a simple "count" request (ActiveRecord::count or
pure SQL) that will not map DB records to Ruby objects, saving much
processing. Once you get the number of records, use this option, like
so :
@records = Book.paginate(..., :total_entries => Book.count)

:count
When you simply do Book.paginate(...) with options, WillPaginate will
do a "count" request first anyway, with the same options. Sometimes,
though, you want to add specific options to the count request : add
them here.


You now have a paginated array of records and can use Ruport as usual.

--
Sylvain Abélard
"J’ai décidé d’être heureux, c’est meilleur pour la santé." -Voltaire

Tygo

unread,
Oct 5, 2009, 7:06:20 AM10/5/09
to Ruby Reports
Hello Sylvain,
Thanks for the tips.

Because I need to use :include with ruport, I needed a count method
that works with Ruport but I didn't found one so I created one myself
- using code from report_table from act_as_reportable (see bellow).
def count_table(number = :all, options = {})
only = options.delete(:only)
except = options.delete(:except)
methods = options.delete(:methods)
includes = options.delete(:include)
filters = options.delete(:filters)
transforms = options.delete(:transforms)
record_class = options.delete(:record_class) ||
Ruport::Data::Record

unless options.delete(:eager_loading) == false
options[:include] = get_include_for_find(includes)
end

count = [*count(number, options)]

end

The code seems to be working well. Can anyone add it to ruport code
base?
Thanks.
Best regards,
Tygo
P.S: Sorry for awaiting this long to reply but I'm on a very tight
schedule...
Reply all
Reply to author
Forward
0 new messages