Skip to content

Commit

Permalink
Support updating while retaining ids
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieuprog committed May 25, 2024
1 parent 512d6bf commit 9bc13e2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
16 changes: 14 additions & 2 deletions lib/polymorphic_embed.ex
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ defmodule PolymorphicEmbed do
type_field: type_field
} = field_options

list_data_for_field = Map.fetch!(changeset.data, field)

embeds =
Enum.map(list_params, fn params ->
case do_get_polymorphic_module_from_map(params, type_field, types_metadata) do
Expand All @@ -275,8 +277,18 @@ defmodule PolymorphicEmbed do
:ignore

module ->
embed_changeset = changeset_fun.(struct(module), params)
embed_changeset = %{embed_changeset | action: :insert}
data_for_field =
Enum.find(list_data_for_field, fn datum ->
datum.id != nil and datum.id == params[:id] and datum.__struct__ == module
end)

embed_changeset =
if data_for_field do
%{changeset_fun.(data_for_field, params) | action: :update}
else
%{changeset_fun.(struct(module), params) | action: :insert}
end

maybe_apply_changes(embed_changeset)
end
end)
Expand Down
26 changes: 26 additions & 0 deletions test/polymorphic_embed_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -1260,6 +1260,32 @@ defmodule PolymorphicEmbedTest do

assert Enum.at(reminder.contexts, 0).id != Enum.at(updated_reminder.contexts, 0).id
assert Enum.at(reminder.contexts, 1).id != Enum.at(updated_reminder.contexts, 1).id

# Assert that we have same ids when the provided context element has an id
attrs = %{
contexts: [
%{
__type__: "device",
id: Enum.at(reminder.contexts, 0).id,
ref: "12345",
type: "cellphone",
address: "address"
},
%{
__type__: "age",
age: "aquarius",
address: "address"
}
]
}

updated_reminder =
reminder
|> reminder_module.changeset(attrs)
|> Repo.update!()

assert Enum.at(reminder.contexts, 0).id == Enum.at(updated_reminder.contexts, 0).id
assert Enum.at(reminder.contexts, 1).id != Enum.at(updated_reminder.contexts, 1).id
end
end

Expand Down

0 comments on commit 9bc13e2

Please sign in to comment.