WillPaginate adds
paginate, per_page and other methods to
ActiveRecord::Base class methods and associations. It also hooks into
method_missing to intercept pagination calls to dynamic
finders such as paginate_by_user_id and translate them to
ordinary finders (find_all_by_user_id in this case).
In short, paginating finders are equivalent to ActiveRecord finders; the only difference is
that we start with “paginate” instead of “find” and that
:page is required parameter:
@posts = Post.paginate :all, :page => params[:page], :order => 'created_at DESC'
In paginating finders, “all” is implicit. There is no sense in
paginating a single record, right? So, you can drop the :all
argument:
Post.paginate(...) => Post.find :all Post.paginate_all_by_something => Post.find_all_by_something Post.paginate_by_something => Post.find_all_by_something
Wraps find_by_sql by simply adding LIMIT and OFFSET to your
SQL string based on the params otherwise used by paginating finds:
page and per_page.
Example:
@developers = Developer.paginate_by_sql ['select * from developers where salary > ?', 80000], :page => params[:page], :per_page => 3
A query for counting rows will automatically be generated if you don’t
supply :total_entries. If you experience problems with this
generated SQL, you might want to perform the count manually in your
application.
# File lib/will_paginate/finders/active_record.rb, line 43 def paginate_by_sql(sql, options) WillPaginate::Collection.create(*wp_parse_options(options)) do |pager| query = sanitize_sql(sql.dup) original_query = query.dup # add limit, offset add_limit! query, :offset => pager.offset, :limit => pager.per_page # perfom the find pager.replace find_by_sql(query) unless pager.total_entries count_query = original_query.sub /\bORDER\s+BY\s+[\w`,\s]+$/i, '' count_query = "SELECT COUNT(*) FROM (#{count_query})" unless ['oracle', 'oci'].include?(self.connection.adapter_name.downcase) count_query << ' AS count_table' end # perform the count query pager.total_entries = count_by_sql(count_query) end end end