# 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?
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
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...
On 23 Set, 08:40, Sylvain Abélard <sylvain.abel...@gmail.com> wrote:
> 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