EctoHooks.Delta (ecto_hooks v2.0.0)
View SourceMetadata struct passed to after_* hooks containing information about the operation.
The Delta struct provides context about which repository operation triggered the hook, allowing for conditional logic and introspection within your hooks.
Fields
:repo_callback- Thec:Ecto.Repofunction that was called (e.g.,:insertforc:Ecto.Repo.insert/2,:getforc:Ecto.Repo.get/3):hook- The hook currently executing (e.g.,:after_insert,:after_get):source- The original input to the repo operation (changeset, queryable, or struct):queryable- Set if source is ant:Ecto.Queryable.t/0(query or schema module):changeset- Set if source is ant:Ecto.Changeset.t/0:record- Set if source is a schema struct or list
Examples
Conditional Hook Logic
def after_get(user, %Delta{repo_callback: :get}) do
# Only log when fetching single users via c:Ecto.Repo.get/3
# (not during c:Ecto.Repo.all/2)
Logger.info("Fetched user: #{user.id}")
user
end
def after_get(user, %Delta{repo_callback: :all}) do
# Skip logging for bulk fetches via c:Ecto.Repo.all/2
user
endInspecting Changes
def after_update(user, %Delta{changeset: changeset}) do
if Ecto.Changeset.changed?(changeset, :email) do
EmailVerification.send_confirmation(user)
end
user
endDelegating to Private Functions
def after_insert(user, delta), do: handle_after_hook(user, delta)
def after_update(user, delta), do: handle_after_hook(user, delta)
defp handle_after_hook(user, %Delta{hook: :after_insert}) do
# Logic specific to inserts
send_welcome_email(user)
user
end
defp handle_after_hook(user, %Delta{hook: :after_update}) do
# Logic specific to updates
invalidate_cache(user)
user
endType
The Delta struct is defined as:
@type t :: %__MODULE__{
repo_callback: repo_callback(),
hook: hook(),
source: term(),
queryable: Ecto.Queryable.t() | nil,
changeset: Ecto.Changeset.t() | nil,
record: struct() | [struct()] | nil
}Where repo_callback() is one of:
:all(c:Ecto.Repo.all/2):delete(c:Ecto.Repo.delete/2):delete!(c:Ecto.Repo.delete!/2):get(c:Ecto.Repo.get/3):get!(c:Ecto.Repo.get!/3):get_by(c:Ecto.Repo.get_by/3):get_by!(c:Ecto.Repo.get_by!/3):insert(c:Ecto.Repo.insert/2):insert!(c:Ecto.Repo.insert!/2):insert_or_update(c:Ecto.Repo.insert_or_update/2):insert_or_update!(c:Ecto.Repo.insert_or_update!/2):one(c:Ecto.Repo.one/2):one!(c:Ecto.Repo.one!/2):preload(c:Ecto.Repo.preload/3):reload(c:Ecto.Repo.reload/2):reload!(c:Ecto.Repo.reload!/2):update(c:Ecto.Repo.update/2):update!(c:Ecto.Repo.update!/2)
And hook() is one of: :after_delete, :after_get, :after_insert, :after_update,
:before_delete, :before_insert, :before_update
Summary
Types
@type hook() ::
:before_update
| :before_insert
| :before_delete
| :after_update
| :after_insert
| :after_get
| :after_delete
@type repo_callback() ::
:update
| :update!
| :preload
| :reload
| :reload!
| :one
| :one!
| :insert_or_update
| :insert_or_update!
| :insert
| :insert!
| :get_by
| :get_by!
| :get
| :get!
| :delete
| :delete!
| :all
Functions
@spec new!(repo_callback(), hook(), source :: any()) :: t() | no_return()