/
write.ex
53 lines (46 loc) · 1.6 KB
/
write.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
defmodule Crit.Setup.AnimalImpl.Write do
alias Ecto.ChangesetX
alias Ecto.Changeset
alias Crit.Setup.Schemas.{Animal, ServiceGap}
alias Crit.Setup.AnimalApi
alias Crit.Sql
def update(animal, attrs, institution) do
case try_update(animal, attrs, institution) do
{:error, %{errors: [{:optimistic_lock_error, _}]}} ->
{:error, changeset_for_lock_error(animal.id, institution)}
{:error, partial_changeset} ->
changeset =
partial_changeset
|> ChangesetX.flush_lock_version
|> changeset_for_other_error
{:error, changeset}
{:ok, result} ->
{:ok, result}
end
end
defp try_update(animal, attrs, institution) do
animal
|> Animal.update_changeset(attrs)
|> Sql.update([stale_error_field: :optimistic_lock_error], institution)
end
defp changeset_for_lock_error(id, institution) do
AnimalApi.updatable!(id, institution)
|> Animal.form_changeset
|> Changeset.add_error(
:optimistic_lock_error,
"Someone else was editing the animal while you were."
)
|> ChangesetX.ensure_forms_display_errors()
end
defp changeset_for_other_error(changeset) do
case Changeset.fetch_change(changeset, :service_gaps) do
{:ok, [ %{action: :insert} | _rest ]} = _has_bad_new_service_gap ->
changeset
{:ok, only_has_service_gap_updates} ->
Changeset.put_change(changeset, :service_gaps,
[Changeset.change(%ServiceGap{}) | only_has_service_gap_updates])
:error ->
%{changeset | data: Animal.prepend_empty_service_gap(changeset.data)}
end
end
end