This gem is the state machinery behind Esse::ActiveRecord::Hooks and Esse::Sequel::Hooks. In most apps, you use the plugin-specific namespace rather than this gem directly.
For end users
If you are using esse-active_record or esse-sequel, use their hook modules:
Esse::ActiveRecord::Hooks.disable!Esse::ActiveRecord::Hooks.enable!
Esse::ActiveRecord::Hooks.without_indexing do # callbacks disabled in this blockend
Esse::ActiveRecord::Hooks.without_indexing(UsersIndex.repo(:user)) do # only that repo disabledend
Esse::ActiveRecord::Hooks.without_indexing_for_model(User, UsersIndex.repo(:user)) do # only User + that repo disabledendCall Esse::Hooks.disable! to disable all registered hook modules (both ActiveRecord and Sequel) at once.
For plugin authors
Use Esse::Hooks[store_key: :unique_key] to create an isolated hook module:
module MyPlugin module Hooks include Esse::Hooks[store_key: :my_plugin_hooks] endend
MyPlugin::Hooks.disable!The store_key identifies the backing Thread.current slot. Choose a unique symbol per plugin.
Registering models
Typically when a model includes your plugin, you register it:
module MyPlugin::Model def self.included(base) MyPlugin::Hooks.register_model(base) endendAfter registration, MyPlugin::Hooks.models lists all models that opted into the system.
Respecting hooks in callbacks
When your plugin runs a callback, check enabled state first:
def on_after_commit(model) return unless MyPlugin::Hooks.enabled_for_model?(model.class, repo) repo.index(document)endGlobal coordination
Any module that include Esse::Hooks[...] is tracked by Esse::Hooks:
Esse::Hooks.hooks# => { esse_active_record_hooks: Esse::ActiveRecord::Hooks,# esse_sequel_hooks: Esse::Sequel::Hooks }
Esse::Hooks.disable! # disables all of themEsse::Hooks.without_indexing # scoped versionReference coercion
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)
Thread safety
State is stored in Thread.current[store_key], so each thread has an independent view. In forking servers (Puma, Sidekiq), children inherit the parent state at fork time.
Scoped blocks (with_indexing / without_indexing) save and restore the current thread’s state even across exceptions.