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
10 changes: 10 additions & 0 deletions lib/polymorphic_embed.ex
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,16 @@ defmodule PolymorphicEmbed do

to_string(type_from_parent_field) != to_string(type_from_map) ->
raise "type specified in the parent field \"#{type_from_parent_field}\" does not match the type in the embedded map \"#{type_from_map}\""

true ->
# type_from_parent_field and type_from_map match
module = get_polymorphic_module_for_type(type_from_parent_field, types_metadata)

if is_nil(data_for_field) or data_for_field.__struct__ != module do
{:insert, struct(module)}
else
{:update, data_for_field}
end
end
else
case get_polymorphic_module_from_map(params, type_field_name, types_metadata) do
Expand Down
29 changes: 29 additions & 0 deletions test/polymorphic_embed_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,35 @@ defmodule PolymorphicEmbedTest do
assert {:error, %Ecto.Changeset{}} = insert_result
end

test "infer type from parent field when type in embed map matches parent field type" do
generator = :polymorphic
reminder_module = get_module(Reminder, generator)

# Both parent field type and embed __type__ are "sms" - they match
sms_reminder_attrs = %{
date: ~U[2020-05-28 02:57:19Z],
text: "This is an SMS reminder #{generator}",
type: "sms",
channel4: %{
__type__: "sms",
number: "02/807.05.53",
country_code: 1,
provider: %{
__type__: "twilio",
api_key: "foo"
}
}
}

insert_result =
struct(reminder_module)
|> reminder_module.changeset(sms_reminder_attrs)
|> Repo.insert()

assert {:ok, %{channel4: %PolymorphicEmbed.Channel.SMS{number: "02/807.05.53"}}} =
insert_result
end

test "validations before casting polymorphic embed still work" do
for generator <- @generators do
reminder_module = get_module(Reminder, generator)
Expand Down
Loading