Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions lib/change_builders/full_diff/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,19 @@ defmodule AshPaperTrail.ChangeBuilders.FullDiff.Helpers do
def unique_id(%Ash.Union{}, dumped_value), do: dumped_value
def unique_id(nil, _dumped_value), do: nil

def unique_id(%{__struct__: resource}, dump_value) do
case Ash.Resource.Info.primary_key(resource) do
[] ->
nil

primary_keys ->
Enum.reduce(primary_keys, [resource], &(&2 ++ [Map.get(dump_value, &1)]))
def unique_id(%{__struct__: resource} = struct, dump_value) do
if Ash.Resource.Info.resource?(resource) do
case Ash.Resource.Info.primary_key(resource) do
[] ->
nil

primary_keys ->
Enum.reduce(primary_keys, [resource], &(&2 ++ [Map.get(dump_value, &1)]))
end
else
# For non-Ash structs (Time, Date, DateTime, Decimal, etc.),
# return the struct itself for value-based equality matching
struct
end
end

Expand Down
35 changes: 35 additions & 0 deletions test/ash_paper_trail/full_diff_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -932,4 +932,39 @@ defmodule AshPaperTrail.FullDiffTest do
} = last_version_changes(ctx.domain, ctx.version_resource)
end
end

describe "full_diff with primitive struct types" do
test "create with {:array, :time} attribute", ctx do
ctx.resource.create!(%{
subject: "Schedule",
times: [~T[08:00:00], ~T[10:00:00], ~T[12:00:00]]
})

assert %{
times: %{
to: [
%{added: ~T[08:00:00], index: %{to: 0}},
%{added: ~T[10:00:00], index: %{to: 1}},
%{added: ~T[12:00:00], index: %{to: 2}}
]
}
} = last_version_changes(ctx.domain, ctx.version_resource)
end

test "update {:array, :time} with reorder, add, and remove", ctx do
post = ctx.resource.create!(%{subject: "Schedule", times: [~T[08:00:00], ~T[10:00:00]]})

ctx.resource.update!(post, %{times: [~T[10:00:00], ~T[08:00:00], ~T[14:00:00]]})

assert %{
times: %{
to: [
%{unchanged: ~T[10:00:00], index: %{from: 1, to: 0}},
%{unchanged: ~T[08:00:00], index: %{from: 0, to: 1}},
%{added: ~T[14:00:00], index: %{to: 2}}
]
}
} = last_version_changes(ctx.domain, ctx.version_resource)
end
end
end
5 changes: 5 additions & 0 deletions test/support/posts/full_diff_post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -104,5 +104,10 @@ defmodule AshPaperTrail.Test.Posts.FullDiffPost do
public? true
allow_nil? true
end

attribute :times, {:array, :time} do
public? true
allow_nil? true
end
end
end