In the past, Ecto provided automatic
callbacks which could
be implemented to run before or after certain database operations using the
Ecto.Model macro
(rather than the modern variant: Ecto.Changeset).
This library provides an a module you can use in your application's MyApp.Repo
module: EctoHooks. Upon invokation, any successful database
Ecto.Repo callbacks will trigger any hooks you've defined in a corresponding
Ecto.Schema module:
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(%Ecto.Changeset{} = changeset) do
Logger.info("inserting new 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
endAlternatively, one can opt to use a more transparent API for initializing
EctoHooks:
def MyApp.Repo do
use EctoHooks.Repo,
otp_app: :my_app,
adapter: Ecto.Adapters.Postgres
endThe 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.
You can install this dependency by adding the following to your application's
mix.exs:
def deps do
[
{:ecto_hooks, "~> 0.1.0"}
]
endSimply add the following line to your application's corresponding MyApp.Repo
module:
use Ecto.Repo.HooksAny time an Ecto.Repo callback successfully returns a struct defined in a
module that use-es Ecto.Model, any corresponding defined hooks are
executed.
All hooks are of arity one, and take only the struct defined in the module as an argument. Hooks are expected to return an updated struct on success, any other value is treated as an error.
A list of valid hooks is listed below:
after_get/1which is executed followingEcto.Repo.all/2,Ecto.Repo.get/3,Ecto.Repo.get!/3,Ecto.Repo.get_by/3,Ecto.Repo.get_by!/3,Ecto.Repo.one/2,Ecto.Repo.one!/2.after_insert/1which is executed followingEcto.Repo.insert/2,Ecto.Repo.insert!/2,Ecto.Repo.insert_or_update/2,Ecto.Repo.insert_or_update!/2after_update/1which is executed followingEcto.Repo.update/2,Ecto.Repo.update!/2,Ecto.Repo.insert_or_update/2,Ecto.Repo.insert_or_update!/2after_delete/1which is executed followingEcto.Repo.delete/2,Ecto.Repo.delete!/2before_insert/1which is executed prior to anEcto.Repo.insert/2,Ecto.Repo.insert!/2,Ecto.Repo.insert_or_update/2,Ecto.Repo.insert_or_update!/2before_update/1which is executed prior to anEcto.Repo.update/2,Ecto.Repo.update!/2,Ecto.Repo.insert_or_update/2,Ecto.Repo.insert_or_update!/2before_delete/1which is executed prior to anEcto.Repo.delete/2,Ecto.Repo.delete!/2