Utworzono widelec z repozytorium ecto
, aby rozszerzyć moduł Ecto.Changeset
o możliwość dodawania ostrzeżeń do zestawu zmian. Chciałem mieć funkcję add_warnings/4
, która dodaje ostrzeżenie do zestawu zmian jako prostą listę ostrzeżeń o tej strukturze warnings: [{atom, {String.t, Keyword.t}}]
, podobną do errors
. Różnica między zachowaniem warnings
i errors
polega na tym, że gdy wystąpi błąd, dane nie są zachowywane, ale po wystąpieniu ostrzeżenia dane są zachowywane.Zestaw zmian Ecto dodaje funkcjonalność ostrzeżeń
Ecto.Changeset
struct rozszerzony z kluczami warnings
i warningless?
: funkcje
defstruct valid?: false, warningless?: false, data: nil, params: nil, changes: %{}, repo: nil,
errors: [], warnings: [], validations: [], required: [], prepare: [],
constraints: [], filters: %{}, action: nil, types: nil,
empty_values: @empty_values
ekto do odlewania, zmiana params przetwórczych itp skorygowanych. Funkcja add_warnings/4
dodania:
@spec add_warning(t, atom, String.t, Keyword.t) :: t
def add_warning(%{warnings: warnings} = changeset, key, message, keys \\ []) when is_binary(message) do
%{changeset | warnings: [{key, {message, keys}}|warnings], warningless?: false}
end
Rezultatem jest to, że mogę otrzymać changeset
z oczekiwanymi klawiszy:
#Ecto.Changeset<action: nil, changes: %{}, data: #Company.Booking<>, errors: [],
valid?: true, warnings: [], warningless?: true>
Kiedy dokonać zmiany z powodu błędu i ostrzeżenia Otrzymuję:
#Ecto.Changeset<action: nil,
changes: %{pickup_address: #Ecto.Changeset<action: :update,
changes: %{street_name: nil}, data: #Company.Address<>,
errors: [street_name: {"can't be blank", [validation: :required]}],
valid?: false,
warnings: [phone_number: {"This phone number is not common in Netherlands",
[]}], warningless?: false>}, data: #Company.Booking<>, errors: [],
valid?: false, warnings: [], warningless?: true>
Więc, wszystko jest zgodne z oczekiwaniami, jeśli chodzi o ostrzeżenia. Następnie, gdy wprowadzę zmianę z ostrzeżeniem, ale bez błędu, otrzymam:
#Ecto.Changeset<action: nil,
changes: %{pickup_address: #Ecto.Changeset<action: :update,
changes: %{street_name: "sss"}, data: #Company.Address<>, errors: [],
valid?: true,
warnings: [phone_number: {"This phone number is not common in Netherlands",
[]}], warningless?: false>}, data: #Company.Booking<>, errors: [],
valid?: true, warnings: [], warningless?: true>
Wszystko jest zgodne z oczekiwaniami. Kiedy nie wprowadzać żadnych zmian w formie nadal powinien otrzymać ostrzeżenie dla numeru telefonu, ale otrzymują:
#Ecto.Changeset<action: nil, changes: %{}, data: #Company.Booking<>, errors: [],
valid?: true, warnings: [], warningless?: true>
mam changeset bez żadnych ostrzeżeń, gdyż nie ma changes
klucz w changeset ponieważ dane nie uległo zmianie.
Pytanie brzmi następująco, jak zaimplementować funkcję ostrzeżeń, aby zawsze mieć ostrzeżenia w zestawie zmian, nawet jeśli nie wprowadzono żadnych zmian?
Nie wyświetlasz żadnej funkcji zmiany zestawu. Prawdopodobnie będziesz chciał użyć ['Ecto.Changeset.get_field/3'] (https://hexdocs.pm/ecto/Ecto.Changeset.html#get_field/3) zamiast [' Ecto.Changeset.get_change /3'](https://hexdocs.pm/ecto/Ecto.Changeset.html#get_change/3) podczas dodawania ostrzeżenia. Jaki jest tego cel? Jeśli chcesz utrwalić dane po ostrzeżeniu, utracisz zestaw zmian i nie będziesz mógł pokazać użytkownikowi wiadomości. –