Skip to content

Commit ed3e4fa

Browse files
committed
go for source_changeset.changes first, fallback to struct field
1 parent 5db99e3 commit ed3e4fa

File tree

2 files changed

+90
-48
lines changed

2 files changed

+90
-48
lines changed

lib/polymorphic_embed/html/helpers.ex

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -53,50 +53,64 @@ if Code.ensure_loaded?(Phoenix.HTML) && Code.ensure_loaded?(Phoenix.HTML.Form) d
5353
id = to_string(form.id <> "_#{field}")
5454
name = to_string(form.name <> "[#{field}]")
5555

56-
params = Map.get(source_changeset.params || %{}, to_string(field), %{})
56+
params = Map.get(source_changeset.params || %{}, to_string(field), %{}) |> List.wrap()
5757

5858
struct = Ecto.Changeset.apply_changes(source_changeset)
5959

60-
list_data =
61-
case Map.get(struct, field) do
62-
nil ->
63-
type = Keyword.get(options, :polymorphic_type, get_polymorphic_type(form, field))
64-
module = PolymorphicEmbed.get_polymorphic_module(struct.__struct__, field, type)
65-
if module, do: [struct(module)], else: []
60+
Map.get(source_changeset.changes, field)
61+
|> case do
62+
nil ->
63+
case Map.get(struct, field) do
64+
nil ->
65+
type = Keyword.get(options, :polymorphic_type, get_polymorphic_type(form, field))
66+
module = PolymorphicEmbed.get_polymorphic_module(struct.__struct__, field, type)
67+
if module, do: [struct(module)], else: []
6668

67-
data ->
68-
List.wrap(data)
69-
end
69+
data ->
70+
List.wrap(data)
71+
end
7072

71-
list_data
73+
data when is_list(data) ->
74+
data
75+
76+
data ->
77+
List.wrap(data)
78+
end
7279
|> Enum.with_index()
73-
|> Enum.map(fn {data, i} ->
74-
params =
75-
case params do
76-
nil ->
77-
%{}
80+
|> Enum.map(fn
81+
{%Ecto.Changeset{} = changeset, i} ->
82+
params = changeset.params || %{}
83+
errors = get_errors(changeset)
7884

79-
params when is_list(params) ->
80-
Enum.at(params, i) || %{}
85+
%{changeset: changeset, params: params, errors: errors, index: i}
8186

82-
params when is_map(params) ->
83-
Map.get(params, to_string(i), %{})
84-
end
87+
{data, i} ->
88+
params = Enum.at(params, i) || %{}
8589

86-
changeset =
87-
data
88-
|> Ecto.Changeset.change()
89-
|> apply_action(parent_action)
90+
changeset =
91+
data
92+
|> Ecto.Changeset.change()
93+
|> apply_action(parent_action)
9094

91-
errors = get_errors(changeset)
95+
errors = get_errors(changeset)
9296

93-
changeset = %Ecto.Changeset{
94-
changeset
95-
| action: parent_action,
96-
params: params,
97-
errors: errors,
98-
valid?: errors == []
99-
}
97+
changeset = %{
98+
changeset
99+
| action: parent_action,
100+
params: params,
101+
errors: errors,
102+
valid?: errors == []
103+
}
104+
105+
%{changeset: changeset, params: params, errors: errors, index: i}
106+
end)
107+
|> Enum.map(fn prepared_data ->
108+
%{
109+
changeset: changeset,
110+
params: params,
111+
errors: errors,
112+
index: i
113+
} = prepared_data
100114

101115
%schema{} = source_changeset.data
102116

@@ -116,7 +130,8 @@ if Code.ensure_loaded?(Phoenix.HTML) && Code.ensure_loaded?(Phoenix.HTML.Form) d
116130
name: if(array?, do: name <> "[" <> index_string <> "]", else: name),
117131
index: if(array?, do: i),
118132
errors: errors,
119-
data: data,
133+
data: changeset.data,
134+
action: parent_action,
120135
params: params,
121136
hidden: [{type_field_name, to_string(type)}],
122137
options: options

test/polymorphic_embed_test.exs

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,15 +2704,26 @@ defmodule PolymorphicEmbedTest do
27042704
for generator <- @generators do
27052705
reminder_module = get_module(Reminder, generator)
27062706

2707-
attrs = %{
2708-
date: ~U[2020-05-28 02:57:19Z],
2709-
text: "This is an Email reminder",
2710-
channel: %{
2711-
address: "a",
2712-
valid: true,
2713-
confirmed: true
2714-
}
2715-
}
2707+
attrs =
2708+
if polymorphic?(generator) do
2709+
%{
2710+
date: ~U[2020-05-28 02:57:19Z],
2711+
text: "This is an Email reminder",
2712+
channel: %{
2713+
address: "a",
2714+
valid: true,
2715+
confirmed: true
2716+
}
2717+
}
2718+
else
2719+
%{
2720+
number: ~U[2020-05-28 02:57:19Z],
2721+
text: "This is a non polymorphic reminder",
2722+
channel: %{
2723+
number: "a"
2724+
}
2725+
}
2726+
end
27162727

27172728
changeset =
27182729
struct(reminder_module)
@@ -2721,8 +2732,19 @@ defmodule PolymorphicEmbedTest do
27212732
contents =
27222733
safe_inputs_for(changeset, :channel, generator, fn f ->
27232734
assert f.impl == Phoenix.HTML.FormData.Ecto.Changeset
2724-
assert f.errors == []
2725-
text_input(f, :address)
2735+
2736+
if polymorphic?(generator) do
2737+
assert f.errors == [
2738+
{:address,
2739+
{"should be at least %{count} character(s)",
2740+
[count: 3, validation: :length, kind: :min, type: :string]}}
2741+
]
2742+
2743+
text_input(f, :address)
2744+
else
2745+
assert f.errors == []
2746+
text_input(f, :number)
2747+
end
27262748
end)
27272749

27282750
expected_contents =
@@ -2732,7 +2754,7 @@ defmodule PolymorphicEmbedTest do
27322754
<input id="reminder_channel_address" name="reminder[channel][address]" type="text" value="a">
27332755
""",
27342756
else: ~s"""
2735-
<input id="reminder_channel_address" name="reminder[channel][address]" type="text" value="a">
2757+
<input id="reminder_channel_number" name="reminder[channel][number]" type="text" value="a">
27362758
"""
27372759
)
27382760

@@ -2745,7 +2767,12 @@ defmodule PolymorphicEmbedTest do
27452767
generator,
27462768
fn f ->
27472769
assert f.impl == Phoenix.HTML.FormData.Ecto.Changeset
2748-
text_input(f, :address)
2770+
2771+
if polymorphic?(generator) do
2772+
text_input(f, :address)
2773+
else
2774+
text_input(f, :number)
2775+
end
27492776
end
27502777
)
27512778

@@ -2756,7 +2783,7 @@ defmodule PolymorphicEmbedTest do
27562783
<input id="reminder_channel_address" name="reminder[channel][address]" type="text" value="a">
27572784
""",
27582785
else: ~s"""
2759-
<input id="reminder_channel_address" name="reminder[channel][address]" type="text" value="a">
2786+
<input id="reminder_channel_number" name="reminder[channel][number]" type="text" value="a">
27602787
"""
27612788
)
27622789

0 commit comments

Comments
 (0)