EctoTrailer (ecto_trailer v1.0.0)

EctoTrailer allows to store changeset changes into a separate audit_log table.

Usage

  1. Add ecto_trailer to your list of dependencies in mix.exs:

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

  2. Add a migration that creates audit_log table to priv/repo/migrations folder:

    defmodule EctoTrailer.TestRepo.Migrations.CreateAuditLogTable do @moduledoc false use Ecto.Migration

    def change do

     create table(:audit_log, primary_key: false) do
       add :id, :uuid, primary_key: true
       add :actor_id, :string, null: false
       add :resource, :string, null: false
       add :resource_id, :string, null: false
       add :changeset, :map, null: false
    
       timestamps([type: :utc_datetime, updated_at: false])
     end

    end end

  3. Use EctoTrailer in your repo:

    defmodule MyApp.Repo do use Ecto.Repo, otp_app: :my_app use EctoTrailer end

  4. Use logging functions instead of defaults. See EctoTrailer module docs.

Summary

Functions

Call Ecto.Repo.delete/2 operation and store deleted objext in a change_log table.

Call Ecto.Repo.insert/2 operation and store changes in a change_log table.

Store bulk changes in a change_log table.

Call Ecto.Repo.update/2 operation and store changes in a change_log table.

Call c:Ecto.Repo.upsert/2 operation and store changes in a change_log table.

Types

action_type()

@type action_type() :: :insert | :update | :upsert | :delete

Functions

delete_and_log(repo, struct_or_changeset, actor_id, opts \\ [])

@spec delete_and_log(
  repo :: Ecto.Repo.t(),
  struct_or_changeset :: Ecto.Schema.t() | Ecto.Changeset.t(),
  actor_id :: String.T,
  opts :: Keyword.t()
) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}

Call Ecto.Repo.delete/2 operation and store deleted objext in a change_log table.

insert_and_log(repo, struct_or_changeset, actor_id, opts \\ [])

@spec insert_and_log(
  repo :: Ecto.Repo.t(),
  struct_or_changeset :: Ecto.Schema.t() | Ecto.Changeset.t(),
  actor_id :: String.T,
  opts :: Keyword.t()
) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}

Call Ecto.Repo.insert/2 operation and store changes in a change_log table.

Insert arguments, return and options same as Ecto.Repo.insert/2 has.

log(repo, struct_or_changeset, changes, actor_id, action_type)

@spec log(
  repo :: Ecto.Repo.t(),
  struct_or_changeset :: Ecto.Schema.t() | Ecto.Changeset.t(),
  changes :: map(),
  actor_id :: String.T,
  action_type :: action_type()
) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}

Store changes in a change_log table.

log_bulk(repo, structs, changes, actor_id, action_type)

@spec log_bulk(
  repo :: Ecto.Repo.t(),
  structs :: [Ecto.Schema.t()],
  changes :: [map()],
  actor_id :: String.t(),
  action_type :: action_type()
) :: :ok

Store bulk changes in a change_log table.

update_and_log(repo, changeset, actor_id, opts \\ [])

@spec update_and_log(
  repo :: Ecto.Repo.t(),
  changeset :: Ecto.Changeset.t(),
  actor_id :: String.T,
  opts :: Keyword.t()
) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}

Call Ecto.Repo.update/2 operation and store changes in a change_log table.

Insert arguments, return and options same as Ecto.Repo.update/2 has.

upsert_and_log(repo, struct_or_changeset, actor_id, opts \\ [])

@spec upsert_and_log(
  repo :: Ecto.Repo.t(),
  struct_or_changeset :: Ecto.Schema.t() | Ecto.Changeset.t(),
  actor_id :: String.T,
  opts :: Keyword.t()
) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}

Call c:Ecto.Repo.upsert/2 operation and store changes in a change_log table.

Insert arguments, return and options same as c:Ecto.Repo.upsert/2 has.