Skip to content

Commit d6c58c7

Browse files
authored
fix: handle non-Ash structs in full_diff unique_id helper (#213)
* test: add full_diff tests for primitive struct types * test: update full_diff tests for primitive struct types Verify {:array, :time} attributes work correctly with the unique_id/2 fix.
1 parent 17bc491 commit d6c58c7

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

lib/change_builders/full_diff/helpers.ex

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,19 @@ defmodule AshPaperTrail.ChangeBuilders.FullDiff.Helpers do
9898
def unique_id(%Ash.Union{}, dumped_value), do: dumped_value
9999
def unique_id(nil, _dumped_value), do: nil
100100

101-
def unique_id(%{__struct__: resource}, dump_value) do
102-
case Ash.Resource.Info.primary_key(resource) do
103-
[] ->
104-
nil
105-
106-
primary_keys ->
107-
Enum.reduce(primary_keys, [resource], &(&2 ++ [Map.get(dump_value, &1)]))
101+
def unique_id(%{__struct__: resource} = struct, dump_value) do
102+
if Ash.Resource.Info.resource?(resource) do
103+
case Ash.Resource.Info.primary_key(resource) do
104+
[] ->
105+
nil
106+
107+
primary_keys ->
108+
Enum.reduce(primary_keys, [resource], &(&2 ++ [Map.get(dump_value, &1)]))
109+
end
110+
else
111+
# For non-Ash structs (Time, Date, DateTime, Decimal, etc.),
112+
# return the struct itself for value-based equality matching
113+
struct
108114
end
109115
end
110116

test/ash_paper_trail/full_diff_test.exs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,4 +932,39 @@ defmodule AshPaperTrail.FullDiffTest do
932932
} = last_version_changes(ctx.domain, ctx.version_resource)
933933
end
934934
end
935+
936+
describe "full_diff with primitive struct types" do
937+
test "create with {:array, :time} attribute", ctx do
938+
ctx.resource.create!(%{
939+
subject: "Schedule",
940+
times: [~T[08:00:00], ~T[10:00:00], ~T[12:00:00]]
941+
})
942+
943+
assert %{
944+
times: %{
945+
to: [
946+
%{added: ~T[08:00:00], index: %{to: 0}},
947+
%{added: ~T[10:00:00], index: %{to: 1}},
948+
%{added: ~T[12:00:00], index: %{to: 2}}
949+
]
950+
}
951+
} = last_version_changes(ctx.domain, ctx.version_resource)
952+
end
953+
954+
test "update {:array, :time} with reorder, add, and remove", ctx do
955+
post = ctx.resource.create!(%{subject: "Schedule", times: [~T[08:00:00], ~T[10:00:00]]})
956+
957+
ctx.resource.update!(post, %{times: [~T[10:00:00], ~T[08:00:00], ~T[14:00:00]]})
958+
959+
assert %{
960+
times: %{
961+
to: [
962+
%{unchanged: ~T[10:00:00], index: %{from: 1, to: 0}},
963+
%{unchanged: ~T[08:00:00], index: %{from: 0, to: 1}},
964+
%{added: ~T[14:00:00], index: %{to: 2}}
965+
]
966+
}
967+
} = last_version_changes(ctx.domain, ctx.version_resource)
968+
end
969+
end
935970
end

test/support/posts/full_diff_post.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,5 +104,10 @@ defmodule AshPaperTrail.Test.Posts.FullDiffPost do
104104
public? true
105105
allow_nil? true
106106
end
107+
108+
attribute :times, {:array, :time} do
109+
public? true
110+
allow_nil? true
111+
end
107112
end
108113
end

0 commit comments

Comments
 (0)