Module: OccamsRecord

Defined in:
lib/occams-record/version.rb,
lib/occams-record.rb,
lib/occams-record/ugly.rb,
lib/occams-record/merge.rb,
lib/occams-record/pluck.rb,
lib/occams-record/query.rb,
lib/occams-record/cursor.rb,
lib/occams-record/errors.rb,
lib/occams-record/raw_query.rb,
lib/occams-record/measureable.rb,
lib/occams-record/results/row.rb,
lib/occams-record/type_caster.rb,
lib/occams-record/binds_converter.rb,
lib/occams-record/results/results.rb,
lib/occams-record/eager_loaders/base.rb,
lib/occams-record/eager_loaders/habtm.rb,
lib/occams-record/eager_loaders/tracer.rb,
lib/occams-record/binds_converter/named.rb,
lib/occams-record/eager_loaders/builder.rb,
lib/occams-record/eager_loaders/context.rb,
lib/occams-record/eager_loaders/has_one.rb,
lib/occams-record/eager_loaders/through.rb,
lib/occams-record/batches/cursor_helpers.rb,
lib/occams-record/eager_loaders/has_many.rb,
lib/occams-record/binds_converter/abstract.rb,
lib/occams-record/eager_loaders/ad_hoc_one.rb,
lib/occams-record/eager_loaders/belongs_to.rb,
lib/occams-record/eager_loaders/ad_hoc_base.rb,
lib/occams-record/eager_loaders/ad_hoc_many.rb,
lib/occams-record/binds_converter/positional.rb,
lib/occams-record/batches/offset_limit/scoped.rb,
lib/occams-record/eager_loaders/eager_loaders.rb,
lib/occams-record/batches/offset_limit/raw_query.rb,
lib/occams-record/eager_loaders/polymorphic_belongs_to.rb

Overview

Main entry point for using OccamsRecord.

Defined Under Namespace

Modules: Batches, BindsConverter, EagerLoaders, Measureable, Pluck, Results, TypeCaster, Ugly Classes: Cursor, Measurement, Measurements, Merge, MissingColumnError, MissingDataError, MissingEagerLoadError, NotFound, Query, RawQuery

Constant Summary collapse

VERSION =
"1.12.0".freeze

Class Method Summary collapse

Class Method Details

.query(scope, use: nil, active_record_fallback: nil, query_logger: nil) ⇒ OccamsRecord::Query

Starts building a OccamsRecord::Query. Pass it a scope from any of ActiveRecord’s query builder methods or associations. If you want to eager loaded associations, do NOT use ActiveRecord for it. Instead use OccamsRecord::Query#eager_load. Finally, call ‘run` (or any Enumerable method) to run the query and get back an array of objects.

results = OccamsRecord
  .query(Widget.order("name"))
  .eager_load(:category)
  .eager_load(:order_items, ->(q) { q.select("widget_id, order_id") }) {
    eager_load(:orders) {
      eager_load(:customer, ->(q) { q.select("name") })
    }
  }
  .run

Parameters:

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

    optional Module to include in the result class

  • query_logger (Array) (defaults to: nil)

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

  • active_record_fallback (Symbol) (defaults to: nil)

    If passed, missing methods will be forwarded to an ActiveRecord instance. Options are :lazy (allow lazy loading in the AR record) or :strict (require strict loading)

Returns:



24
25
26
# File 'lib/occams-record/query.rb', line 24

def self.query(scope, use: nil, active_record_fallback: nil, query_logger: nil)
  Query.new(scope, use: use, query_logger: query_logger, active_record_fallback: active_record_fallback)
end

.sql(sql, binds, use: nil, query_logger: nil) ⇒ OccamsRecord::RawQuery

Starts building a OccamsRecord::RawQuery. Pass it a raw SQL statement, optionally followed by a Hash or Array of binds. While this doesn’t offer an additional performance boost, it’s a nice way to write safe, complicated SQL by hand while also supporting eager loading.

results = OccamsRecord.sql("
  SELECT * FROM widgets
  WHERE category_id = %{cat_id}
", {
  cat_id: 5
}).run

If you want to do eager loading, you must first the define a model to pull the associations from (unless you’re using the raw SQL eager loaders ‘eager_load_one` or `eager_load_many`).

results = OccamsRecord
  .sql("
    SELECT * FROM widgets
    WHERE category_id IN (%{cat_ids})
  ", {
    cat_ids: [5, 10]
  })
  .model(Widget)
  .eager_load(:category)
  .run

NOTE To use find_each/find_in_batches, your SQL string must include ‘LIMIT %batch_limit OFFSET %batch_offset’, and an ORDER BY is strongly recomended. OccamsRecord will provide the bind values for you.

NOTE There is variation of the types of values returned (e.g. a Date object vs a date string) depending on the database and ActiveRecord version being used:

Postgres always returns native Ruby types.

SQLite will return native types for the following: integers, floats, string/text. For booleans it will return 0|1 for AR 6+, and “t|f” for AR 5-. Dates and times will be ISO8601 formatted strings. It is possible to coerce the SQLite adapter into returning native types for everything IF they’re columns of a table that you have an AR model for. e.g. if you’re selecting from the widgets, table: ‘OccamsRecord.sql(“…”).model(Widget)…`.

MySQL Mostly native Ruby types, but more testing is needed.

Parameters:

  • sql (String)

    The SELECT statement to run. Binds may be Rails-style (?, :foo) or Ruby-style (%s, %foo).

  • binds (Hash)

    Bind values as Hash (with Symbol keys) or an Array

  • 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

Returns:



50
51
52
# File 'lib/occams-record/raw_query.rb', line 50

def self.sql(sql, binds, use: nil, query_logger: nil)
  RawQuery.new(sql, binds, use: use, query_logger: nil)
end