Whatwasit v0.2.1 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 # 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.
Install with the --whodoneit
option:
mix whodoneit.install --whodoneit
Update the model
defmodule MyProject.Post do
use MyProject.Web, :model
use Whatwasit
# ...
def changeset(model, params \ %{}, opts \ []) do
model
|> cast(params, ~w(title body))
|> validate_required(~w(title body)a)
|> prepare_version(opts)
end
end
Update the controller
defmodule MyProject.PostController do
# ...
# Add this
defp whodoneit(conn) do
user = Coherence.current_user(conn)
[whodoneit: user , whodoneit_name: user.name]
end
def update(conn, %{"id" => id, "post" => post_params}) do
post = Repo.get!(Post, id)
changeset = Post.changeset(post, post_params, whodoneit(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(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"}]