Skip to content

Commit c9e1a1d

Browse files
authored
Merge pull request #2 from woylie/fix-get-type
Fix get type
2 parents 78e51d9 + 27c2668 commit c9e1a1d

File tree

6 files changed

+127
-11
lines changed

6 files changed

+127
-11
lines changed

.github/workflows/ci.yml

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
name: CI
22

3+
env:
4+
ELIXIR_VERSION: "1.14"
5+
OTP_VERSION: "25.1"
6+
37
on:
48
push:
59
branches:
@@ -11,7 +15,7 @@ on:
1115
jobs:
1216
test:
1317
runs-on: ubuntu-latest
14-
name: OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}
18+
name: Test OTP ${{matrix.otp}} / Elixir ${{matrix.elixir}}
1519
strategy:
1620
matrix:
1721
otp: ["24.3", "25.1"]
@@ -39,6 +43,7 @@ jobs:
3943
steps:
4044
- uses: actions/checkout@v3
4145
- uses: erlef/setup-beam@v1
46+
id: beam
4247
with:
4348
otp-version: ${{matrix.otp}}
4449
elixir-version: ${{matrix.elixir}}
@@ -50,6 +55,35 @@ jobs:
5055
deps
5156
key: ${{ runner.os }}-otp-${{ steps.beam.outputs.otp-version }}-elixir-${{ steps.beam.outputs.elixir-version }}-mix-${{ hashFiles('mix.lock') }}
5257
restore-keys: ${{ runner.os }}-otp-${{ steps.beam.outputs.otp-version }}-elixir-${{ steps.beam.outputs.elixir-version }}-
58+
- name: Install Dependencies
59+
run: |
60+
mix local.rebar --force
61+
mix local.hex --force
62+
mix deps.get
63+
- name: Run Tests
64+
run: mix coveralls.github
65+
66+
lint:
67+
runs-on: ubuntu-latest
68+
name: Lint
69+
env:
70+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
71+
72+
steps:
73+
- uses: actions/checkout@v3
74+
- uses: erlef/setup-beam@v1
75+
id: beam
76+
with:
77+
otp-version: ${{ env.OTP_VERSION }}
78+
elixir-version: ${{ env.ELIXIR_VERSION}}
79+
- name: Restore dependencies and build cache
80+
uses: actions/cache@v3
81+
with:
82+
path: |
83+
_build
84+
deps
85+
key: ${{ runner.os }}-otp-${{ steps.beam.outputs.otp-version }}-elixir-${{ steps.beam.outputs.elixir-version }}-mix-${{ hashFiles('mix.lock') }}
86+
restore-keys: ${{ runner.os }}-otp-${{ steps.beam.outputs.otp-version }}-elixir-${{ steps.beam.outputs.elixir-version }}-
5387
- name: Restore PLT cache
5488
uses: actions/cache@v3
5589
id: plt_cache
@@ -75,5 +109,3 @@ jobs:
75109
run: mix hex.audit
76110
- name: Generate docs
77111
run: mix docs
78-
- name: Run Tests
79-
run: mix coveralls.github

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,5 @@ polymorphic_embed-*.tar
2828

2929
# Ignore Dialyzer plts file
3030
.plts
31+
32+
.elixir_ls

lib/polymorphic_embed/html/form.ex

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,19 @@ if Code.ensure_loaded?(Phoenix.HTML) && Code.ensure_loaded?(Phoenix.HTML.Form) d
1414
%_{} = value ->
1515
PolymorphicEmbed.get_polymorphic_type(schema, field, value)
1616

17-
_ ->
17+
%{} = map ->
18+
case PolymorphicEmbed.get_polymorphic_module(schema, field, map) do
19+
nil ->
20+
nil
21+
22+
module ->
23+
PolymorphicEmbed.get_polymorphic_type(schema, field, module)
24+
end
25+
26+
list when is_list(list) ->
27+
nil
28+
29+
nil ->
1830
nil
1931
end
2032
end

test/polymorphic_embed_test.exs

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2045,7 +2045,7 @@ defmodule PolymorphicEmbedTest do
20452045
end
20462046

20472047
describe "Form.get_polymorphic_type/3" do
2048-
test "returns type from changeset" do
2048+
test "returns type from changeset via identify_by_fields" do
20492049
reminder_module = get_module(Reminder, :polymorphic)
20502050

20512051
attrs = %{
@@ -2094,9 +2094,9 @@ defmodule PolymorphicEmbedTest do
20942094
end)
20952095
end
20962096

2097-
test "returns type from string parameters" do
2097+
test "returns type from changeset via custom type field" do
20982098
reminder_module = get_module(Reminder, :polymorphic)
2099-
attrs = %{"channel" => %{"my_type_field" => "email"}}
2099+
attrs = %{"channel" => %{"my_type_field" => "sms"}}
21002100

21012101
changeset =
21022102
reminder_module
@@ -2105,30 +2105,81 @@ defmodule PolymorphicEmbedTest do
21052105

21062106
safe_form_for(changeset, fn f ->
21072107
assert PolymorphicEmbed.HTML.Form.get_polymorphic_type(f, reminder_module, :channel) ==
2108+
:sms
2109+
2110+
text_input(f, :text)
2111+
end)
2112+
end
2113+
2114+
test "returns type from map with default type field (string)" do
2115+
reminder_module = get_module(Reminder, :polymorphic)
2116+
attrs = %{"channel2" => %{"__type__" => "email"}}
2117+
2118+
changeset =
2119+
reminder_module
2120+
|> struct()
2121+
|> reminder_module.changeset(attrs)
2122+
2123+
safe_form_for(changeset, fn f ->
2124+
assert PolymorphicEmbed.HTML.Form.get_polymorphic_type(f, reminder_module, :channel2) ==
21082125
:email
21092126

21102127
text_input(f, :text)
21112128
end)
21122129
end
21132130

2114-
test "returns type from atom parameters" do
2131+
test "returns type from map with default type field (atom)" do
21152132
reminder_module = get_module(Reminder, :polymorphic)
2116-
attrs = %{channel: %{my_type_field: :email}}
2133+
attrs = %{"channel2" => %{__type__: :email}}
21172134

21182135
changeset =
21192136
reminder_module
21202137
|> struct()
21212138
|> reminder_module.changeset(attrs)
21222139

21232140
safe_form_for(changeset, fn f ->
2124-
assert PolymorphicEmbed.HTML.Form.get_polymorphic_type(f, reminder_module, :channel) ==
2141+
assert PolymorphicEmbed.HTML.Form.get_polymorphic_type(f, reminder_module, :channel2) ==
2142+
:email
2143+
2144+
text_input(f, :text)
2145+
end)
2146+
end
2147+
2148+
test "returns type from map with custom type field (string)" do
2149+
reminder_module = get_module(Reminder, :polymorphic)
2150+
attrs = %{"channel3" => %{"my_type_field" => "email"}}
2151+
2152+
changeset =
2153+
reminder_module
2154+
|> struct()
2155+
|> reminder_module.changeset(attrs)
2156+
2157+
safe_form_for(changeset, fn f ->
2158+
assert PolymorphicEmbed.HTML.Form.get_polymorphic_type(f, reminder_module, :channel3) ==
2159+
:email
2160+
2161+
text_input(f, :text)
2162+
end)
2163+
end
2164+
2165+
test "returns type from map with custom type field (atom)" do
2166+
reminder_module = get_module(Reminder, :polymorphic)
2167+
attrs = %{"channel3" => %{my_type_field: "email"}}
2168+
2169+
changeset =
2170+
reminder_module
2171+
|> struct()
2172+
|> reminder_module.changeset(attrs)
2173+
2174+
safe_form_for(changeset, fn f ->
2175+
assert PolymorphicEmbed.HTML.Form.get_polymorphic_type(f, reminder_module, :channel3) ==
21252176
:email
21262177

21272178
text_input(f, :text)
21282179
end)
21292180
end
21302181

2131-
test "returns type from parameters while type field is custom" do
2182+
test "returns nil with map when custom type field is configured and default type field is set" do
21322183
reminder_module = get_module(Reminder, :polymorphic)
21332184
attrs = %{channel: %{__type__: :email}}
21342185

test/support/migrations/20000101000000_create_tables.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ defmodule PolymorphicEmbed.CreateTables do
77
add(:text, :text, null: false)
88

99
add(:channel, :map)
10+
add(:channel2, :map)
11+
add(:channel3, :map)
1012
add(:contexts, :map)
1113
add(:contexts2, :map)
1214

test/support/models/polymorphic/reminder.ex

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,23 @@ defmodule PolymorphicEmbed.Reminder do
2020
type_field: :my_type_field
2121
)
2222

23+
polymorphic_embeds_one(:channel2,
24+
types: [
25+
sms: PolymorphicEmbed.Channel.SMS,
26+
email: PolymorphicEmbed.Channel.Email
27+
],
28+
on_replace: :update
29+
)
30+
31+
polymorphic_embeds_one(:channel3,
32+
types: [
33+
sms: PolymorphicEmbed.Channel.SMS,
34+
email: PolymorphicEmbed.Channel.Email
35+
],
36+
on_replace: :update,
37+
type_field: :my_type_field
38+
)
39+
2340
polymorphic_embeds_many(:contexts,
2441
types: [
2542
location: PolymorphicEmbed.Reminder.Context.Location,

0 commit comments

Comments
 (0)