Module: AppQuery::Paginatable

Extended by:
ActiveSupport::Concern
Defined in:
lib/app_query/paginatable.rb

Overview

Note:

This is a BaseQuery middleware. Include it in classes that inherit from BaseQuery and use the +paginate+ ERB helper in your SQL template.

Middleware concern that adds pagination support to BaseQuery subclasses.

Include this module in your query class to enable pagination with Kaminari-compatible result objects.

Provides two modes:

  • With count: Full pagination with page numbers (uses COUNT query)
  • Without count: Simple prev/next for large datasets (uses limit+1 trick)

Examples:

Basic usage

class ApplicationQuery < AppQuery::BaseQuery
  include AppQuery::Paginatable
  per_page 50
end

class ArticlesQuery < ApplicationQuery
  per_page 10
end

# With count (full pagination)
articles = ArticlesQuery.new.paginate(page: 1).entries
articles.total_pages  # => 5
articles.current_page # => 1

# Without count (large datasets)
articles = ArticlesQuery.new.paginate(page: 1, without_count: true).entries
articles.next_page    # => 2 (or nil if last page)

SQL template with pagination

-- app/queries/articles.sql
SELECT * FROM articles
ORDER BY published_on DESC
<%= paginate(page: page, per_page: per_page) %>

See Also:

Defined Under Namespace

Classes: PaginatedResult

Instance Method Summary collapse

Instance Method Details

#entriesPaginatedResult, Array<Hash>

Executes the query and returns paginated results.

Returns:

  • (PaginatedResult)

    when pagination is enabled

  • (Array<Hash>)

    when unpaginated



201
202
203
# File 'lib/app_query/paginatable.rb', line 201

def entries
  @_entries ||= build_paginated_result(super)
end

#paginate(page: 1, per_page: self.class.per_page, without_count: false) ⇒ self

Enables pagination for this query.

Examples:

Standard pagination with total count

ArticlesQuery.new.paginate(page: 2, per_page: 20).entries

Fast pagination without count (for large tables)

ArticlesQuery.new.paginate(page: 1, without_count: true).entries

Parameters:

  • page (Integer) (defaults to: 1)

    page number, starting at 1

  • per_page (Integer) (defaults to: self.class.per_page)

    records per page (defaults to class setting)

  • without_count (Boolean) (defaults to: false)

    skip COUNT query for large datasets

Returns:

  • (self)

    for chaining



178
179
180
181
182
183
# File 'lib/app_query/paginatable.rb', line 178

def paginate(page: 1, per_page: self.class.per_page, without_count: false)
  @page = page
  @per_page = per_page
  @without_count = without_count
  self
end

#total_countInteger

Returns the total count of records (without pagination).

Executes a separate COUNT query. Result is memoized.

Returns:

  • (Integer)

    total number of records



210
211
212
# File 'lib/app_query/paginatable.rb', line 210

def total_count
  @_total_count ||= unpaginated_query.count
end

#unpaginatedself

Disables pagination, returning all results.

Examples:

ArticlesQuery.new.unpaginated.entries # => all records

Returns:

  • (self)

    for chaining



191
192
193
194
195
# File 'lib/app_query/paginatable.rb', line 191

def unpaginated
  @page = nil
  @per_page = nil
  self
end