Whatwasit v0.1.0 Whatwasit
Track changes on Ecto Models.
Whatwasit is a package for tracking changes to your project’s Ecto models for auditing or versioning. Keep track of each change to your model and who made the change. Deletes can be tracked too.
Simply add a 2 line change to each model you would like tracked and a version record will be inserted into the database for each change.
defmodule MyProject.Post do
use MyProject.Web, :model
use Whatwasit.Schema # add this
schema "posts" do
field :title, :string
field :body, :string
timestamps
end
def changeset(model, params \ %{}) do
model
|> cast(params, ~w(title body))
|> validate_required(~w(title body)a)
|> prepare_version # add this
end
end
Pass a changeset into Repo.delete and a version record will be inserted into the database when a model is deleted.
defmodule MyProject.PostController do
# ...
def delete(conn, %{"id" => id}) do
changeset = Repo.get!(Post, id)
|> Post.changeset(%{})
Repo.delete!(changeset)
conn
|> put_flash(:info, "Post deleted successfully.")
|> redirect(to: post_path(conn, :index))
end
end
You can also track who made the change with a few extra changes.
defmodule MyProject.Post do
use MyProject.Web, :model
use Whatwasit.Schema
# ...
def changeset(model, params \ %{}, opts \ []) do
model
|> cast(params, ~w(title body))
|> validate_required(~w(title body)a)
|> prepare_version(opts)
end
end
defmodule Admin.PostController do
# ...
def update(conn, %{"id" => id, "post" => post_params}) do
post = Repo.get!(Post, id)
changeset = Post.changeset(post, post_params, whodoneit: Coherence.current_user(conn))
case Repo.update(changeset) do
{:ok, post} ->
conn
|> put_flash(:info, "Post updated successfully.")
|> redirect(to: post_path(conn, :show, post))
{:error, changeset} ->
render(conn, "edit.html", post: post, changeset: changeset)
end
end
def delete(conn, %{"id" => id}) do
changeset = Repo.get!(Post, id)
|> Post.changeset(%{}, whodoneit: Coherence.current_user(conn))
Repo.delete!(changeset)
conn
|> put_flash(:info, "Post deleted successfully.")
|> redirect(to: post_path(conn, :index))
end
end
Retrieve the versions for a specific record:
iex(4)> post = MyProject.Repo.get MyProject.Post, 9
%MyProject.Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">,
body: "The answer is 42", id: 9,
inserted_at: #Ecto.DateTime<2016-07-22 01:49:25>, title: "What's the Question",
updated_at: #Ecto.DateTime<2016-07-22 01:49:55>}
iex(5)> MyProject.Post.versions post
[%MyProject.Post{__meta__: #Ecto.Schema.Metadata<:loaded, "posts">, body: "42",
id: 9, inserted_at: "2016-07-22T01:49:25", title: "The Answer",
updated_at: "2016-07-22T01:49:25"}]