Class: OccamsRecord::Query

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Batches, EagerLoaders::Builder
Defined in:
lib/occams-record/query.rb

Overview

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from EagerLoaders::Builder

#eager_load, #eager_load_many, #eager_load_one

Methods included from Batches

#find_each, #find_in_batches

Constructor Details

#initialize(scope, use: nil, query_logger: nil, eager_loaders: []) { ... } ⇒ Query

Initialize a new query.

Parameters:

  • scope (ActiveRecord::Relation)
  • use (Array<Module>) (defaults to: nil)

    optional Module to include in the result class (single or array)

  • query_logger (Array) (defaults to: nil)

    (optional) an array into which all queries will be inserted for logging/debug purposes

  • eager_loaders (OccamsRecord::EagerLoaders::Base) (defaults to: [])

Yields:

  • will be eval’d on this instance. Can be used for eager loading. (optional)



52
53
54
55
56
57
58
59
# File 'lib/occams-record/query.rb', line 52

def initialize(scope, use: nil, query_logger: nil, eager_loaders: [], &eval_block)
  @model = scope.klass
  @scope = scope
  @eager_loaders = eager_loaders
  @use = use
  @query_logger = query_logger
  instance_eval(&eval_block) if eval_block
end

Instance Attribute Details

#modelActiveRecord::Base (readonly)

Returns:

  • (ActiveRecord::Base)


35
36
37
# File 'lib/occams-record/query.rb', line 35

def model
  @model
end

#scopeActiveRecord::Relation (readonly)

Returns scope for building the main SQL query.

Returns:

  • (ActiveRecord::Relation)

    scope for building the main SQL query



37
38
39
# File 'lib/occams-record/query.rb', line 37

def scope
  @scope
end

Instance Method Details

#countInteger

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

Returns:

  • (Integer)


98
99
100
# File 'lib/occams-record/query.rb', line 98

def count
  scope.count
end

#each {|OccamsRecord::Results::Row| ... } ⇒ Object

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

Yields:

Returns:

  • Enumerable



118
119
120
121
122
123
124
# File 'lib/occams-record/query.rb', line 118

def each
  if block_given?
    to_a.each { |row| yield row }
  else
    to_a.each
  end
end

#firstOccamsRecord::Results::Row

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



107
108
109
# File 'lib/occams-record/query.rb', line 107

def first
  run { |q| q.limit 1 }.first
end

#run {|ActiveRecord::Relation| ... } ⇒ Array<OccamsRecord::Results::Row> Also known as: to_a

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

Yields:

  • (ActiveRecord::Relation)

    You may use this to return and run a modified relation

Returns:



81
82
83
84
85
86
87
88
89
# File 'lib/occams-record/query.rb', line 81

def run
  sql = block_given? ? yield(scope).to_sql : scope.to_sql
  @query_logger << sql if @query_logger
  result = model.connection.exec_query sql
  row_class = OccamsRecord::Results.klass(result.columns, result.column_types, @eager_loaders.map(&:name), model: model, modules: @use)
  rows = result.rows.map { |row| row_class.new row }
  eager_load! rows
  rows
end