class OccamsRecord::Query

Represents a query to be run and eager associations to be loaded. Use OccamsRecord.query to create your queries instead of instantiating objects directly.

Attributes

model[R]

@return [ActiveRecord::Base]

scope[R]

@return [ActiveRecord::Relation] scope for building the main SQL query

Public Class Methods

new(scope, use: nil, eager_loaders: nil, query_logger: nil, measurements: nil) click to toggle source

Initialize a new query.

@param scope [ActiveRecord::Relation] @param use [Array<Module>] optional Module to include in the result class (single or array) @param query_logger [Array] (optional) an array into which all queries will be inserted for logging/debug purposes @param eager_loaders [OccamsRecord::EagerLoaders::Context] @param measurements [Array]

# File lib/occams-record/query.rb, line 53
def initialize(scope, use: nil, eager_loaders: nil, query_logger: nil, measurements: nil)
  @model = scope.klass
  @scope = scope
  @eager_loaders = eager_loaders || EagerLoaders::Context.new(@model)
  @use = use
  @query_logger, @measurements = query_logger, measurements
end

Public Instance Methods

count() click to toggle source

Returns the number of rows that will be returned if the query is run.

@return [Integer]

# File lib/occams-record/query.rb, line 120
def count
  scope.count
end
each() { |row| ... } click to toggle source

If you pass a block, each result row will be yielded to it. If you don't, an Enumerable will be returned.

@yield [OccamsRecord::Results::Row] @return Enumerable

# File lib/occams-record/query.rb, line 150
def each
  if block_given?
    to_a.each { |row| yield row }
  else
    to_a.each
  end
end
first() click to toggle source

Run the query with LIMIT 1 and return the first result (which could be nil).

@return [OccamsRecord::Results::Row]

# File lib/occams-record/query.rb, line 129
def first
  run { |q| q.limit 1 }.first
end
first!() click to toggle source

Run the query with LIMIT 1 and return the first result. If nothing is found an OccamsRecord::NotFound exception will be raised.

@return [OccamsRecord::Results::Row]

# File lib/occams-record/query.rb, line 139
def first!
  first || raise(OccamsRecord::NotFound.new(model.name, scope.where_values_hash))
end
query() { |scope| ... } click to toggle source

Returns a new Query object with a modified scope.

@yield [ActiveRecord::Relation] the current scope which you may modify and return @return [OccamsRecord::Query]

# File lib/occams-record/query.rb, line 67
def query
  scope = block_given? ? yield(@scope) : @scope
  Query.new(scope, use: @use, eager_loaders: @eager_loaders, query_logger: @query_logger)
end
run() { |scope| ... } click to toggle source

Run the query and return the results.

You may optionally pass a block to modify the query just before it's run (the change will NOT persist). This is very useful for running paginated queries.

occams = OccamsRecord.query(Widget.all)

# returns first 100 rows
occams.run { |q| q.offset(0).limit(100) }

# returns second 100 rows
occams.run { |q| q.offset(100).limit(100) }

# returns ALL rows
occams.run

Any Enumerable method (e.g. each, to_a, map, reduce, etc.) may be used instead. Additionally, `find_each` and `find_in_batches` are available.

@yield [ActiveRecord::Relation] You may use this to return and run a modified relation @return [Array<OccamsRecord::Results::Row>]

# File lib/occams-record/query.rb, line 95
def run
  sql = block_given? ? yield(scope).to_sql : scope.to_sql
  @query_logger << sql if @query_logger
  result = if measure?
             record_start_time!
             measure!(model.table_name, sql) {
               model.connection.exec_query sql
             }
           else
             model.connection.exec_query sql
           end
  row_class = OccamsRecord::Results.klass(result.columns, result.column_types, @eager_loaders.names, model: model, modules: @use)
  rows = result.rows.map { |row| row_class.new row }
  @eager_loaders.run!(rows, query_logger: @query_logger, measurements: @measurements)
  yield_measurements!
  rows
end
Also aliased as: to_a
to_a()
Alias for: run