Skip to content

Commit b7484e6

Browse files
committed
fixed casting empty embedded schemas with use_parent_field_for_type
1 parent 17b5c76 commit b7484e6

4 files changed

Lines changed: 56 additions & 4 deletions

File tree

lib/polymorphic_embed.ex

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,6 @@ defmodule PolymorphicEmbed do
172172
{:ok, nil} when not required ->
173173
Ecto.Changeset.put_change(changeset, field, nil)
174174

175-
{:ok, map} when map == %{} and not array? ->
176-
changeset
177-
178175
{:ok, params_for_field} when array? ->
179176
create_sort_default = fn -> sort_create(Enum.into(cast_opts, %{}), field_opts) end
180177
params_for_field = apply_sort_drop(params_for_field, sort, drop, create_sort_default)

test/polymorphic_embed_test.exs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,49 @@ defmodule PolymorphicEmbedTest do
228228
insert_result
229229
end
230230

231+
test "infer type from parent field and cast an empty embed" do
232+
generator = :polymorphic
233+
reminder_module = get_module(Reminder, generator)
234+
235+
reminder_attrs = %{
236+
date: DateTime.utc_now(),
237+
text: "This is a reminder #{generator}",
238+
type: "not_provided",
239+
channel4: %{}
240+
}
241+
242+
insert_result =
243+
struct(reminder_module)
244+
|> reminder_module.changeset(reminder_attrs)
245+
|> Repo.insert()
246+
247+
assert {:ok, %{id: id, channel4: %PolymorphicEmbed.Channel.NotProvided{}}} =
248+
insert_result
249+
250+
assert %{channel4: %PolymorphicEmbed.Channel.NotProvided{}} = Repo.get!(reminder_module, id)
251+
end
252+
253+
test "cannot cast an empty embed when no type can be inferred" do
254+
generator = :polymorphic
255+
reminder_module = get_module(Reminder, generator)
256+
257+
reminder_attrs = %{
258+
date: DateTime.utc_now(),
259+
text: "This is a reminder #{generator}",
260+
channel2: %{}
261+
}
262+
263+
insert_result =
264+
struct(reminder_module)
265+
|> reminder_module.changeset(reminder_attrs)
266+
|> Repo.insert()
267+
268+
assert {:error, changeset} = insert_result
269+
270+
assert changeset.errors == [channel2: {"is invalid", []}]
271+
refute changeset.valid?
272+
end
273+
231274
test "validations before casting polymorphic embed still work" do
232275
for generator <- @generators do
233276
reminder_module = get_module(Reminder, generator)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
defmodule PolymorphicEmbed.Channel.NotProvided do
2+
use Ecto.Schema
3+
import Ecto.Changeset
4+
5+
embedded_schema do
6+
end
7+
8+
def changeset(struct, attrs) do
9+
cast(struct, attrs, [])
10+
end
11+
end

test/support/models/polymorphic/reminder.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ defmodule PolymorphicEmbed.Reminder do
4545
polymorphic_embeds_one(:channel4,
4646
types: [
4747
sms: PolymorphicEmbed.Channel.SMS,
48-
email: PolymorphicEmbed.Channel.Email
48+
email: PolymorphicEmbed.Channel.Email,
49+
not_provided: PolymorphicEmbed.Channel.NotProvided
4950
],
5051
on_replace: :update,
5152
use_parent_field_for_type: :type

0 commit comments

Comments
 (0)