Skip to content

samgaw-archive/ecto_hooks

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EctoHooks

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
end

Alternatively, 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
end

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.

Links

Installation

You can install this dependency by adding the following to your application's mix.exs:

def deps do
  [
    {:ecto_hooks, "~> 0.1.0"}
  ]
end

Usage

Simply add the following line to your application's corresponding MyApp.Repo module:

use Ecto.Repo.Hooks

Any 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/1 which is executed following Ecto.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/1 which is executed following Ecto.Repo.insert/2, Ecto.Repo.insert!/2, Ecto.Repo.insert_or_update/2, Ecto.Repo.insert_or_update!/2
  • after_update/1 which is executed following Ecto.Repo.update/2, Ecto.Repo.update!/2, Ecto.Repo.insert_or_update/2, Ecto.Repo.insert_or_update!/2
  • after_delete/1 which is executed following Ecto.Repo.delete/2, Ecto.Repo.delete!/2
  • before_insert/1 which is executed prior to an Ecto.Repo.insert/2, Ecto.Repo.insert!/2, Ecto.Repo.insert_or_update/2, Ecto.Repo.insert_or_update!/2
  • before_update/1 which is executed prior to an Ecto.Repo.update/2, Ecto.Repo.update!/2, Ecto.Repo.insert_or_update/2, Ecto.Repo.insert_or_update!/2
  • before_delete/1 which is executed prior to an Ecto.Repo.delete/2, Ecto.Repo.delete!/2

About

Ecto addon that re-implements Ecto.Model callbacks

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Elixir 99.7%
  • Nix 0.3%