ex_audit
ex_audit copied to clipboard
implement insert_all
This PR implements the track changes for insert_all
. Unlike PR https://github.com/ZennerIoT/ex_audit/pull/34 the default return behavior of this function on Ecto is preserved.
References https://github.com/ZennerIoT/ex_audit/issues/19
Thanks for this, I will review it later this week
Hi! Any updates on this one? :-)
Hi! Any updates on this one? :-)
I am waiting on @narrowtux feedback here https://github.com/ZennerIoT/ex_audit/pull/63#discussion_r615435576
Also looking forward for this
Hey, whats the state of this PR ?
ping
Hello, I'm sorry I have put off reviewing this for so long. The truth is, I don't really like the magic behaviour of the overridden insert/update/delete functions any more. I think with the simpler functions it works because there is only 1-2 ways of using them: either passing a changeset or a complete struct.
With insert_all, there is a lot more potential of things going wrong when plugging it into existing applications, since there are a lot more ways to use this function (did you know you can pass a query instead of a list of maps) and I'm not confident it won't break any of our various usages of insert_all in our apps and other already in-production apps from other users of this library.
If I would write ex_audit again today, I would probably force users of this library to be more explicit about when they want to track changes and which changes they want to track, instead of magically detecting them and dealing with lots of garbage data in the versions table later (we've had to deal with that in our in-production app).
I've written this code that can be used when wanting to track changes in combination with batched inserts/deletes, which can probably be extended to update_all as well, but that would require the original structs to be loaded before updating them:
items = Repo.insert_all(Item, values)
now = DateTime.utc_now()
custom_data = ExAudit.CustomData.get() |> Enum.into(%{})
compare = case action do
:created -> &ExAudit.Tracking.compare_versions(:created, %{}, &1)
:deleted -> &ExAudit.Tracking.compare_versions(:deleted, &1, %{})
end
tracked_changes =
items
|> Enum.flat_map(compare)
|> Enum.map(&Map.merge(&1, %{recorded_at: now, id: Ecto.UUID.generate()}))
|> Enum.map(&Map.merge(&1, custom_data))
Repo.insert_all(MyApp.ExAuditVersion, tracked_changes)