EctoHooks (ecto_hooks v1.0.1) View Source
When use
-ed in a module that also use
-es Ecto.Repo
, augments the following
Ecto.Repo
callbacks to provide user definable hooks following successful
execution.
Hooks to MyApp.EctoSchema.after_get/2
:
all/2
get/3
get!/3
get_by/3
get_by!/3
one/2
one!/2
Hooks to MyApp.EctoSchema.after_delete/2
:
delete/2
delete!/2
Hooks to MyApp.EctoSchema.after_insert/2
:
insert/2
insert!/2
Hooks to MyApp.EctoSchema.after_update/2
:
update/2
update!/2
Hooks to MyApp.EctoSchema.after_insert/2
or to MyApp.Ecto.Schema.after_update/2
:
insert_or_update/2
insert_or_update!/2
Hooks to MyApp.EctoSchema.before_delete/1
:
delete/2
delete!/2
Hooks to MyApp.EctoSchema.before_insert/1
:
insert/2
insert!/2
Hooks to MyApp.EctoSchema.before_update/1
:
update/2
update!/2
Hooks to MyApp.EctoSchema.before_insert/1
or to MyApp.Ecto.Schema.before_update/1
:
insert_or_update/2
insert_or_update!/2
Please note that for all after_*
hooks, the result of executing a MyApp.Repo.*
callback
is what ultimately gets returned from the hook, and thus you should aim to write logic
that is transparent and does not break the expected semantics or behaviour of said
callback.
Any results wrapped within an {:ok, _}
or {:error, _}
are also returned re-wrapped
as expected.
Also, all after_*
hooks are provided an EctoHooks.Delta
struct as a second parameter,
which in some cases can be helpful for intuiting the diff between the result before
versus after running a repo operation. Please see the docs pertaining to EctoHooks.Delta
for more information.
For all before_*
hooks, the result returned by hook is passed directly to the MyApp.Repo.*
callback called and thus care must be made to be aware of any implicit changes to changesets
prior to writing to the database.
The hooking functionality provided by EctoHooks
can be pretty useful for resolving
virtual fields, but can also prove useful for centralising some logging or telemetry
logic.
All defined hooks are executed synchronously immediately before or after calling into
your configured database. To prevent the potential for hooks to infinite loop before
returning, by default, EctoHooks will not trigger more than once within a single
Repo call. You can opt out of this via calling EctoHooks.enable_hooks/0
in any
of your defined hooks.
This infinite loop protection only currently works within a given process. Take care when a defined hook may spawn other processes which may trigger database updates which themselves result in hooks being called.
Example usage:
def MyApp.Repo do
use Ecto.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
use EctoHooks
end
def MyApp.User do
use Ecto.Changeset
require Logger
schema "users" do
field :first_name, :string
field :last_name, :string
field :full_name, :string, virtual: true
end
def before_insert(changeset) do
Logger.warning("updating a user...")
changeset
end
def after_get(%__MODULE__{} = user, %EctoHooks.Delta{}) do
%__MODULE__{user | full_name: user.first_name <> " " <> user.last_name}
end
end
Link to this section Summary
Functions
Disables EctoHooks from running for all future Repo operations in the current process.
Enables EctoHooks from running for all future Repo operations in the current process.
Returns a boolean indicating if EctoHooks are enabled in the current process.
Link to this section Functions
Disables EctoHooks from running for all future Repo operations in the current process.
Enables EctoHooks from running for all future Repo operations in the current process.
Returns a boolean indicating if EctoHooks are enabled in the current process.