API Reference

Esse::Plugins::ActiveRecord

The plugin module. Registered via:

class MyIndex < Esse::Index
plugin :active_record
end

Repository class methods

collection(model, **opts, &block)

Replaces the default collection DSL. Accepts a class inheriting from ::ActiveRecord::Base or an ::ActiveRecord::Relation.

ArgumentDescription
modelAR class or relation
batch_size:Records per batch (default 1000)
connect_with:Hash of {role:, shard:} for connection switching
&blockBlock evaluated in the collection class scope — use for scope / batch_context / connected_to

Returns an Esse::ActiveRecord::Collection subclass.

dataset(**params)

Returns the current filtered ActiveRecord::Relation (applies scopes).


Esse::ActiveRecord::Collection

Base class for collections built from ActiveRecord models. Subclasses are created automatically by the collection DSL.

Class-level DSL

scope(name, proc = nil, override: false, &block)

Define a named scope.

collection ::User do
scope :active, -> { where(active: true) }
scope :role, ->(role) { where(role: role) }
end

batch_context(name, proc = nil, override: false, &block)

Define a batch enrichment fetcher — invoked once per batch with (records, **ctx).

collection ::Order do
batch_context :customers do |orders, **|
Customer.where(id: orders.map(&:customer_id)).index_by(&:id)
end
end

connected_to(**kwargs)

Set database role/shard:

collection ::User do
connected_to(role: :reading)
end

Instance methods

MethodDescription
`each {rows, **ctx
`each_batch_ids {ids
count / sizeTotal rows after scopes applied
dataset(**kwargs)Return filtered ActiveRecord::Relation

Constructor:

CollectionClass.new(start: 1, finish: 10_000, batch_size: 500, **scope_args)
ParamDescription
startPrimary key lower bound (inclusive)
finishPrimary key upper bound (inclusive)
batch_sizeOverrides class default
**paramsScope arguments and extra where-conditions

Esse::ActiveRecord::Model

Mixin for ActiveRecord models. include it to register callbacks.

index_callback(reference, on: [...], with: nil, **opts, &block)

Registers an after_commit callback that indexes the model into a repository.

ParamDescription
reference'index_name' or 'index_name:repo_name' (or class-constant form)
on:Which events — any subset of [:create, :update, :destroy]. Default: all three.
with::update for partial updates, nil (default) for full reindex
if: / unless:Same semantics as AR after_commit
&blockOptional — return the object to index (default: self)

Raises ArgumentError if the same repo already has a callback registered.

update_lazy_attribute_callback(reference, attribute, on: [...], **opts, &block)

Registers a callback that calls repo.update_documents_attribute(attribute, ids, opts) on commit.

update_lazy_attribute_callback('posts_index:post', 'comments_count') { post_id }

The block returns the ID (or array of IDs) of the document to update.

without_indexing(*repos, &block)

Temporarily disables callbacks for this model class.

User.without_indexing { User.create!(...) }
User.without_indexing(UsersIndex) { User.create!(...) }

esse_callbacks

Returns a frozen hash of registered callbacks:

User.esse_callbacks
# => { 'users_index:user' => { create_indexing: [klass, opts, block], ... } }

Esse::ActiveRecord::Hooks

Global state for enabling/disabling indexing callbacks. Uses esse-hooks under the hood.

disable! / enable!

Toggle callbacks globally:

Esse::ActiveRecord::Hooks.disable!
# ... bulk work ...
Esse::ActiveRecord::Hooks.enable!

without_indexing(*repos, &block)

Scoped disable, auto-restores state after the block.

Esse::ActiveRecord::Hooks.without_indexing do
...
end
Esse::ActiveRecord::Hooks.without_indexing(UsersIndex.repo(:user)) do
...
end

with_indexing(*repos, &block)

Opposite — forces enabling in a scope.

enabled?(repo = nil) / disabled?(repo = nil)

Check global or per-repo status.

resolve_index_repository(reference)

Resolve a string reference to a repository instance:

Esse::ActiveRecord::Hooks.resolve_index_repository('users_index:user')
# => UsersIndex.repo(:user)

Supported forms:

  • 'users'
  • 'users_index'
  • 'users_index:user'
  • 'UsersIndex'
  • 'UsersIndex::User'
  • 'foo/v1/users_index/user' (namespaced)

register_model(model_class) / models

Used internally by index_callback to track model classes that have callbacks.


Built-in callback classes

Registered in Esse::ActiveRecord::Callbacks. All inherit from Esse::ActiveRecord::Callback.

CallbackRegistered asBehavior
IndexingOnCreate:create_indexingCalls repo.index(doc) on create
IndexingOnUpdate:update_indexingCalls repo.update(doc) or repo.index(doc) (depending on with:). If routing changed, deletes the previous document at the old routing.
IndexingOnDestroy:destroy_indexingCalls repo.delete(doc) on destroy. Silently handles NotFoundError.
UpdateLazyAttribute:create_update_lazy_attribute, :update_update_lazy_attribute, :destroy_update_lazy_attributeCalls repo.update_documents_attribute(attribute, ids, opts)

Custom callbacks

Subclass Esse::ActiveRecord::Callback:

class MyCallback < Esse::ActiveRecord::Callback
def call(model)
# ...
end
end
Esse::ActiveRecord::Callbacks.register_callback(:my_thing, :create, MyCallback)

Then reference it through your own DSL — use the built-in mechanism as a template.


Deprecated methods

DeprecatedUse instead
index_callbacksindex_callback
esse_index_reposesse_callbacks