Packages
paper_trail
0.0.5
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 PaperTrail.Version
@doc """
Gets all the versions of a record given a module and its id
"""
def get_versions(model, id) do
item_type = model |> Module.split |> List.last
version_query(item_type, id) |> Repo.all
end
@doc """
Gets all the versions of a record
"""
def get_versions(record) do
item_type = record.__struct__ |> Module.split |> List.last
version_query(item_type, record.id) |> Repo.all
end
@doc """
Gets the last version of a record given its module reference and its id
"""
def get_version(model, id) do
item_type = Module.split(model) |> List.last
last(version_query(item_type, id)) |> Repo.one
end
@doc """
Gets the last version of a record
"""
def get_version(record) do
item_type = record.__struct__ |> Module.split |> List.last
last(version_query(item_type, record.id)) |> Repo.one
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)
@doc """
Inserts a record to the database with a related version insertion in one transaction
"""
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)
Repo.insert(version)
end)
|> Repo.transaction
end
# might make the changeset version
@doc """
Updates a record from the database with a related version insertion in one transaction
"""
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)
Repo.insert(version)
end)
|> Repo.transaction
end
@doc """
Deletes a record from the database with a related version insertion in one transaction
"""
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)
Repo.insert(version)
end)
|> Repo.transaction
end
defp 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
defp make_version_struct(%{event: "update"}, changeset, meta) do
%Version{
event: "update",
item_type: changeset.data.__struct__ |> Module.split |> List.last,
item_id: changeset.data.id,
item_changes: changeset.changes,
meta: meta
}
end
defp 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