changed
CHANGELOG.md
|
@@ -2,6 +2,14 @@
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+ ## [0.1.2] - 2021-08-29
|
6
|
+
|
7
|
+ ### Fixed
|
8
|
+
|
9
|
+ - Handle `Ecto.Association.NotLoaded` structs when appending, prepending or
|
10
|
+ inserting data into relations that are child relations of newly added, not
|
11
|
+ persisted data.
|
12
|
+
|
5
13
|
## [0.1.1] - 2021-08-28
|
6
14
|
|
7
15
|
### Changed
|
changed
README.md
|
@@ -11,7 +11,7 @@ Add `ecto_nested_changeset` to your list of dependencies in `mix.exs`:
|
11
11
|
```elixir
|
12
12
|
def deps do
|
13
13
|
[
|
14
|
- {:ecto_nested_changeset, "~> 0.1.1"}
|
14
|
+ {:ecto_nested_changeset, "~> 0.1.2"}
|
15
15
|
]
|
16
16
|
end
|
17
17
|
```
|
changed
hex_metadata.config
|
@@ -17,4 +17,4 @@
|
17
17
|
{<<"optional">>,false},
|
18
18
|
{<<"repository">>,<<"hexpm">>},
|
19
19
|
{<<"requirement">>,<<"~> 3.7">>}]]}.
|
20
|
- {<<"version">>,<<"0.1.1">>}.
|
20
|
+ {<<"version">>,<<"0.1.2">>}.
|
changed
lib/ecto_nested_changeset.ex
|
@@ -8,6 +8,7 @@ defmodule EctoNestedChangeset do
|
8
8
|
|
9
9
|
import Ecto.Changeset
|
10
10
|
|
11
|
+ alias Ecto.Association.NotLoaded
|
11
12
|
alias Ecto.Changeset
|
12
13
|
|
13
14
|
@doc """
|
|
@@ -98,9 +99,12 @@ defmodule EctoNestedChangeset do
|
98
99
|
|
99
100
|
The path may lead to any field, including arrays and relation fields. Unlike
|
100
101
|
`Ecto.Changeset.update_change/3`, the update function is always applied,
|
101
|
- either to the change or to existing value. The values will not be unwrapped,
|
102
|
- which means that the update function passed as the last parameter must
|
103
|
- potentially handle either changesets or raw values, depending on the path.
|
102
|
+ either to the change or to existing value.
|
103
|
+
|
104
|
+ If the path points to a field with a simple type, the update function will
|
105
|
+ receive the raw value of the field. However, if the path points to the field
|
106
|
+ of a *-to-many relation, the list values will not be unwrapped, which means
|
107
|
+ that the update function has to handle a list of changesets.
|
104
108
|
|
105
109
|
## Examples
|
106
110
|
|
|
@@ -212,11 +216,13 @@ defmodule EctoNestedChangeset do
|
212
216
|
|
213
217
|
defp nested_update(:append, %Changeset{} = changeset, [field], value)
|
214
218
|
when is_atom(field) do
|
215
|
- Changeset.put_change(
|
216
|
- changeset,
|
217
|
- field,
|
218
|
- get_change_or_field(changeset, field) ++ [value]
|
219
|
- )
|
219
|
+ new_value =
|
220
|
+ case {get_change_or_field(changeset, field), changeset.action} do
|
221
|
+ {%NotLoaded{}, :insert} -> [value]
|
222
|
+ {previous_value, _} -> previous_value ++ [value]
|
223
|
+ end
|
224
|
+
|
225
|
+ Changeset.put_change(changeset, field, new_value)
|
220
226
|
end
|
221
227
|
|
222
228
|
defp nested_update(:append, %{} = data, [field], value) when is_atom(field) do
|
|
@@ -227,11 +233,13 @@ defmodule EctoNestedChangeset do
|
227
233
|
|
228
234
|
defp nested_update(:prepend, %Changeset{} = changeset, [field], value)
|
229
235
|
when is_atom(field) do
|
230
|
- Changeset.put_change(
|
231
|
- changeset,
|
232
|
- field,
|
233
|
- [value | get_change_or_field(changeset, field)]
|
234
|
- )
|
236
|
+ new_value =
|
237
|
+ case {get_change_or_field(changeset, field), changeset.action} do
|
238
|
+ {%NotLoaded{}, :insert} -> [value]
|
239
|
+ {previous_value, _} -> [value | previous_value]
|
240
|
+ end
|
241
|
+
|
242
|
+ Changeset.put_change(changeset, field, new_value)
|
235
243
|
end
|
236
244
|
|
237
245
|
defp nested_update(:prepend, %{} = data, [field], value)
|
|
@@ -246,6 +254,17 @@ defmodule EctoNestedChangeset do
|
246
254
|
List.insert_at(items, index, value)
|
247
255
|
end
|
248
256
|
|
257
|
+ defp nested_update(:insert, %Changeset{} = changeset, [field, index], value)
|
258
|
+ when is_atom(field) and is_integer(index) do
|
259
|
+ new_value =
|
260
|
+ case {get_change_or_field(changeset, field), changeset.action} do
|
261
|
+ {%NotLoaded{}, :insert} -> [value]
|
262
|
+ {previous_value, _} -> List.insert_at(previous_value, index, value)
|
263
|
+ end
|
264
|
+
|
265
|
+ Changeset.put_change(changeset, field, new_value)
|
266
|
+ end
|
267
|
+
|
249
268
|
defp nested_update(:update, %Changeset{} = changeset, [field], func)
|
250
269
|
when is_atom(field) do
|
251
270
|
value = get_change_or_field(changeset, field)
|
changed
mix.exs
|
@@ -1,7 +1,7 @@
|
1
1
|
defmodule EctoNestedChangeset.MixProject do
|
2
2
|
use Mix.Project
|
3
3
|
|
4
|
- @version "0.1.1"
|
4
|
+ @version "0.1.2"
|
5
5
|
@source_url "https://github.com/woylie/ecto_nested_changeset"
|
6
6
|
|
7
7
|
def project do
|