Packages
paper_trail
0.0.3
1.1.2
1.1.1
1.1.0
1.0.0
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.0
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.1
0.10.0
0.9.0
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.3
0.5.2
0.5.0
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.9
0.0.8
0.0.7
0.0.6
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Track and record all the changes in your database. Revert back to anytime in history.
Current section
Files
Jump to
Current section
Files
lib/paper_trail.ex
defmodule PaperTrail do
alias Ecto.Multi
import Ecto.Query
alias Model.Version
def get_versions(model, id) do
item_type = model |> Module.split |> List.last
version_query(item_type, id) |> Application.Repo.all
end
def get_versions(changeset) do
item_type = changeset.__struct__ |> Module.split |> List.last
version_query(item_type, changeset.id) |> Application.Repo.all # where id, item_type last inserted_at
end
def get_version(model, id) do
item_type = Module.split(model) |> List.last
version_query(item_type, id) |> Application.Repo.one
end
def get_version(changeset) do
item_type = changeset.__struct__ |> Module.split |> List.last
last(version_query(item_type, changeset.id)) |> Application.Repo.one # where id, item_type last inserted_at
end
defp version_query(item_type, id) do
from v in Version,
where: v.item_type == ^item_type and v.item_id == ^id
end
# changeset = Model.changeset(Ecto.Repo.get(Model, id), params)
def insert(struct, meta \\ nil) do
Multi.new
|> Multi.insert(:model, struct)
|> Multi.run(:version, fn %{model: model} ->
version = make_version_struct(%{event: "create"}, model, meta)
Application.Repo.insert(version)
end)
|> Application.Repo.transaction
end
def update(changeset, meta \\ nil) do
Multi.new
|> Multi.update(:model, changeset)
|> Multi.run(:version, fn %{model: model} ->
version = make_version_struct(%{event: "update"}, changeset, meta)
Application.Repo.insert(version)
end)
|> Application.Repo.transaction
end
def delete(struct, meta \\ nil) do
Multi.new
|> Multi.delete(:model, struct)
|> Multi.run(:version, fn %{model: model} ->
version = make_version_struct(%{event: "destroy"}, model, meta)
Application.Repo.insert(version)
end)
|> Application.Repo.transaction
end
def make_version_struct(%{event: "create"}, model, meta) do
%Version{
event: "create",
item_type: model.__struct__ |> Module.split |> List.last,
item_id: model.id,
item_changes: Map.drop(model, [:__struct__, :__meta__]),
meta: meta
}
end
def make_version_struct(%{event: "update"}, changeset, meta) do
%Version{
event: "create",
item_type: changeset.data.__struct__ |> Module.split |> List.last,
item_id: changeset.data.id,
item_changes: changeset.changes,
meta: meta
}
end
def make_version_struct(%{event: "destroy"}, model, meta) do
%Version{
event: "destroy",
item_type: model.__struct__ |> Module.split |> List.last,
item_id: model.id,
item_changes: Map.drop(model, [:__struct__, :__meta__]),
meta: meta
}
end
end