EctoHooks (ecto_hooks v0.3.0) 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/1
:
all/2
get/3
get!/3
get_by/3
get_by!/3
one/2
one!/2
Hooks to MyApp.EctoSchema.after_delete/1
:
delete/2
delete!/2
Hooks to MyApp.EctoSchema.after_insert/1
:
insert/2
insert!/2
Hooks to MyApp.EctoSchema.after_update/1
:
update/2
update!/2
Hooks to MyApp.EctoSchema.after_insert/1
or to MyApp.Ecto.Schema.after_update/1
:
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.
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. Note that because any business logic is executed synchronously after the
hooked Ecto.Repo
callback, one should avoid doing any blocking or potentially
terminating logic within hooks as weird or strange behaviour may occur.
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__{first_name: first_name, last_name: last_name} = user) do
%__MODULE__{user | full_name: first_name <> " " <> last_name}
end
end