diff --git a/example/user.ex b/example/user.ex index 26a5507..1e25ea9 100644 --- a/example/user.ex +++ b/example/user.ex @@ -4,6 +4,7 @@ defmodule ExAudit.Test.User do @derive {ExAudit.Tracker, except: [:transient_field]} + @primary_key {:user_id, :id, autogenerate: true} schema "users" do field :email, :string field :name, :string diff --git a/lib/repo/queryable.ex b/lib/repo/queryable.ex index 445df50..bf80bcb 100644 --- a/lib/repo/queryable.ex +++ b/lib/repo/queryable.ex @@ -32,12 +32,17 @@ defmodule ExAudit.Queryable do # from v in query, # where: v.entity_id == subquery(from q in struct, select: q.id), # where: v.entity_schema == ^struct - %{__struct__: struct, id: id} when nil not in [struct, id] -> - from( - v in query, - where: v.entity_id == ^id, - where: v.entity_schema == ^struct - ) + %{__struct__: schema} when not is_nil(schema) -> + [primary_key] = schema.__schema__(:primary_key) + id = Map.get(struct, primary_key) + + if not is_nil(id) do + from( + v in query, + where: v.entity_id == ^id, + where: v.entity_schema == ^schema + ) + end end versions = Ecto.Repo.Queryable.all(module, query, Ecto.Repo.Supervisor.tuplet(module, opts)) @@ -74,13 +79,16 @@ defmodule ExAudit.Queryable do end end - def history_query(%{id: id, __struct__: struct}) do + def history_query(%{__struct__: schema} = struct) do + [primary_key] = schema.__schema__(:primary_key) + id = Map.get(struct, primary_key) + from( - v in version_schema(), - where: v.entity_id == ^id, - where: v.entity_schema == ^struct, - order_by: [desc: :recorded_at] - ) + v in version_schema(), + where: v.entity_id == ^id, + where: v.entity_schema == ^schema, + order_by: [desc: :recorded_at] + ) end @drop_fields [:__meta__, :__struct__] @@ -103,7 +111,12 @@ defmodule ExAudit.Queryable do # get the referenced struct as it exists now - struct = module.one(from(s in version.entity_schema, where: s.id == ^version.entity_id)) + [primary_key] = version.entity_schema.__schema__(:primary_key) + + struct = + module.one( + from(s in version.entity_schema, where: field(s, ^primary_key) == ^version.entity_id) + ) result = Enum.reduce(versions, struct, &_revert/2) diff --git a/lib/tracking/tracking.ex b/lib/tracking/tracking.ex index 801224f..5b1e75f 100644 --- a/lib/tracking/tracking.ex +++ b/lib/tracking/tracking.ex @@ -37,8 +37,10 @@ defmodule ExAudit.Tracking do [] patch -> + [primary_key] = schema.__schema__(:primary_key) + params = %{ - entity_id: Map.get(old, :id) || Map.get(new, :id), + entity_id: Map.get(old, primary_key) || Map.get(new, primary_key), entity_schema: schema, patch: patch, action: action diff --git a/priv/repo/migrations/20231207230932_change_user_primary_key_name.exs b/priv/repo/migrations/20231207230932_change_user_primary_key_name.exs new file mode 100644 index 0000000..44e8d56 --- /dev/null +++ b/priv/repo/migrations/20231207230932_change_user_primary_key_name.exs @@ -0,0 +1,7 @@ +defmodule ExAudit.Test.Repo.Migrations.ChangeUserPrimaryKeyName do + use Ecto.Migration + + def change do + rename table(:users), :id, to: :user_id + end +end diff --git a/test/assoc_test.exs b/test/assoc_test.exs index 9dda9b0..9c811e6 100644 --- a/test/assoc_test.exs +++ b/test/assoc_test.exs @@ -8,15 +8,15 @@ defmodule AssocTest do test "comment lifecycle tracked" do user = Util.create_user() - ExAudit.track(actor_id: user.id) + ExAudit.track(actor_id: user.user_id) params = %{ title: "Controversial post", - author_id: user.id, + author_id: user.user_id, comments: [ %{ body: "lorem impusdrfnia", - author_id: user.id + author_id: user.user_id } ] } @@ -26,7 +26,7 @@ defmodule AssocTest do [%{actor_id: actor_id}] = comment_history = Repo.history(comment) assert length(comment_history) == 1 - assert actor_id == user.id + assert actor_id == user.user_id end test "structs configured as primitives are treated as primitives" do @@ -52,23 +52,23 @@ defmodule AssocTest do test "should track cascading deletions (before they happen)" do user = Util.create_user() - ExAudit.track(actor_id: user.id) + ExAudit.track(actor_id: user.user_id) params = %{ title: "Controversial post", - author_id: user.id, + author_id: user.user_id, comments: [ %{ body: "lorem impusdrfnia", - author_id: user.id + author_id: user.user_id }, %{ body: "That's a nice article", - author_id: user.id + author_id: user.user_id }, %{ body: "We want more of this CONTENT", - author_id: user.id + author_id: user.user_id } ] } @@ -95,7 +95,7 @@ defmodule AssocTest do test "should return changesets from constraint errors" do user = Util.create_user() - ch = UserGroup.changeset(%UserGroup{}, %{name: "a group", user_id: user.id}) + ch = UserGroup.changeset(%UserGroup{}, %{name: "a group", user_id: user.user_id}) {:ok, _group} = Repo.insert(ch) import Ecto.Changeset @@ -103,7 +103,7 @@ defmodule AssocTest do deletion = user |> change - |> no_assoc_constraint(:groups) + |> no_assoc_constraint(:groups, name: :user_groups_user_id_fkey) assert {:error, %Ecto.Changeset{}} = Repo.delete(deletion) end diff --git a/test/ex_audit_test.exs b/test/ex_audit_test.exs index f82c25e..2a1a77c 100644 --- a/test/ex_audit_test.exs +++ b/test/ex_audit_test.exs @@ -22,7 +22,7 @@ defmodule ExAuditTest do version = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, where: v.action == ^:created ) @@ -43,7 +43,7 @@ defmodule ExAuditTest do version = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, where: v.action == ^:updated ) @@ -57,7 +57,7 @@ defmodule ExAuditTest do version = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, where: v.action == ^:deleted ) @@ -75,11 +75,11 @@ defmodule ExAuditTest do changeset = BlogPost.changeset(%BlogPost{}, %{ - author_id: user.id, + author_id: user.user_id, title: "My First Post" }) - {:ok, blog_post} = Repo.insert(changeset, ex_audit_custom: [actor_id: user.id]) + {:ok, blog_post} = Repo.insert(changeset, ex_audit_custom: [actor_id: user.user_id]) version = Repo.one( @@ -90,7 +90,7 @@ defmodule ExAuditTest do ) ) - assert version.actor_id == user.id + assert version.actor_id == user.user_id end test "should track insert_or_update!" do @@ -110,7 +110,7 @@ defmodule ExAuditTest do created = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, where: v.action == ^:created ) @@ -119,7 +119,7 @@ defmodule ExAuditTest do updated = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, where: v.action == ^:updated ) @@ -128,7 +128,7 @@ defmodule ExAuditTest do assert 2 = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, select: count(v.id) ) @@ -163,7 +163,7 @@ defmodule ExAuditTest do created = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, where: v.action == ^:created ) @@ -172,7 +172,7 @@ defmodule ExAuditTest do updated = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, where: v.action == ^:updated ) @@ -181,7 +181,7 @@ defmodule ExAuditTest do assert 2 = Repo.one( from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User, select: count(v.id) ) @@ -206,11 +206,11 @@ defmodule ExAuditTest do changeset = BlogPost.changeset(%BlogPost{}, %{ - author_id: user.id, + author_id: user.user_id, title: "My Second Post" }) - ExAudit.track(actor_id: user.id) + ExAudit.track(actor_id: user.user_id) {:ok, blog_post} = Repo.insert(changeset) @@ -223,7 +223,7 @@ defmodule ExAuditTest do ) ) - assert version.actor_id == user.id + assert version.actor_id == user.user_id end test "does not track changes to ignored fields" do @@ -239,7 +239,7 @@ defmodule ExAuditTest do query = from(v in Version, - where: v.entity_id == ^user.id, + where: v.entity_id == ^user.user_id, where: v.entity_schema == ^User ) @@ -261,7 +261,7 @@ defmodule ExAuditTest do end test "returns a queryable", %{user: user} do - assert user |> Repo.history_query() |> Repo.all() |> Enum.count() == 1 + assert user |> Repo.history_query() |> Repo.all() |> Enum.count() == 1 end end end diff --git a/test/revert_test.exs b/test/revert_test.exs index e4a78d8..6654918 100644 --- a/test/revert_test.exs +++ b/test/revert_test.exs @@ -8,7 +8,7 @@ defmodule RevertTest do test "should revert changes" do user = Util.create_user() - ExAudit.track(actor_id: user.id) + ExAudit.track(actor_id: user.user_id) user2 = Util.create_user("Horst Dieter Schaf", "horst.dieter@schaf.de") @@ -21,7 +21,7 @@ defmodule RevertTest do version = Repo.one( from(v in Version, - where: v.entity_id == ^user2.id, + where: v.entity_id == ^user2.user_id, where: v.entity_schema == ^User, where: v.action == ^:updated ) @@ -36,7 +36,7 @@ defmodule RevertTest do version_rollback = Repo.one( from(v in Version, - where: v.entity_id == ^user2.id, + where: v.entity_id == ^user2.user_id, where: v.entity_schema == ^User, where: v.action == ^:updated, where: v.rollback == true @@ -56,7 +56,7 @@ defmodule RevertTest do version_rollback = Repo.one( from(v in Version, - where: v.entity_id == ^user2.id, + where: v.entity_id == ^user2.user_id, where: v.entity_schema == ^User, where: v.action == ^:updated, where: v.rollback == true, @@ -74,6 +74,6 @@ defmodule RevertTest do assert [version] = Repo.history(user) assert {:ok, nil} = Repo.revert(version) - assert nil == Repo.get(User, user.id) + assert nil == Repo.get(User, user.user_id) end end