Class: Quo::RelationResults

Inherits:
Results
  • Object
show all
Defined in:
lib/quo/relation_results.rb,
sig/generated/quo/relation_results.rbs

Overview

Results wrapper for relation-backed queries providing pagination and counting

Constant Summary

Constants inherited from Results

Quo::Results::FILTER_METHODS, Quo::Results::PAIR_FILTER_METHODS, Quo::Results::PASSTHROUGH_METHODS

Instance Method Summary collapse

Methods inherited from Results

#count, #empty?, #group_by, #method_missing, #page_size, #respond_to_missing?, #size, #transform?, #transform_pair, #transform_results

Constructor Details

#initialize(query, transformer: nil) ⇒ RelationResults

Returns a new instance of RelationResults.

Parameters:

  • query (Quo::Query)
  • transformer: (^(untyped, ?Integer) -> untyped, nil) (defaults to: nil)


11
12
13
14
15
16
# File 'lib/quo/relation_results.rb', line 11

def initialize(query, transformer: nil)
  raise ArgumentError, "Query must be a RelationBackedQuery" unless query.is_a?(Quo::RelationBackedQuery)
  @query = query
  @configured_query = query.unwrap
  @transformer = transformer
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Quo::Results

Instance Method Details

#count_query(query) ⇒ Integer

Note we reselect the query as this prevents query errors if the SELECT clause is not compatible with COUNT (SQLException: wrong number of arguments to function COUNT()). We do this in two ways, either with the primary key or with Arel.star. The primary key is the most compatible way to count, but if the query does not have a primary we fallback. The fallback "*" wont work in certain situations though, specifically if we have a limit() on the query which Arel constructs as a subquery. In this case we will get a SQL error as the generated SQL contains SELECT COUNT(count_column) FROM (SELECT * AS count_column FROM ...) subquery_for_count where the error is: ActiveRecord::StatementInvalid: SQLite3::SQLException: near "AS": syntax error Either way DB engines know how to count efficiently.

Parameters:

  • query (ActiveRecord::Relation)

Returns:

  • (Integer)


50
51
52
53
54
55
56
57
# File 'lib/quo/relation_results.rb', line 50

def count_query(query)
  pk = query.model.primary_key
  if pk
    query.reselect(pk).count
  else
    query.reselect(Arel.star).count
  end
end

#exists?Boolean

Are there any results for this query?

Returns:

  • (Boolean)


19
20
21
22
# File 'lib/quo/relation_results.rb', line 19

def exists? #: bool
  return @configured_query.exists? if @query.relation?
  @configured_query.present?
end

#page_countInteger

Gets the actual count of elements in the page of results (assuming paging is being used, otherwise the count of all results)

Returns:

  • (Integer)


31
32
33
# File 'lib/quo/relation_results.rb', line 31

def page_count #: Integer
  count_query(@configured_query)
end

#total_countInteger

Gets the count of all results ignoring the current page and page size (if set).

Returns:

  • (Integer)


25
26
27
# File 'lib/quo/relation_results.rb', line 25

def total_count #: Integer
  count_query(@query.unwrap_unpaginated)
end