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