6

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?

+0

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. –

Odpowiedz

0

Należy rozważyć do wstępnego wypełnienia ostrzeżenia na samym początku funkcji każdy changeset byś Create - ponieważ nie można używać plug nie można wymyślić, aby napisać makro, które będą obsługiwać tę logikę dla ciebie, jest __using__ doradził, więc byłoby całkiem łatwo odróżnić logikę od domyślnej logiki Ecto.

Twoja walidacja nie powinna dodawać ostrzeżeń do listy ostrzeżeń, ale musisz ją wdrożyć w inny sposób - jeśli to pole jest w porządku, usuniesz już istniejące ostrzeżenia z tej listy. W ten sposób będziesz pewny, że twój zestaw zmian jest w porządku, gdy jest warningless, ponieważ usunął on wszystkie ostrzeżenia z tej listy i działałby idealnie dla pustych zmian w zestawie zmian.