Я создал форк репозитория ecto
, чтобы расширить модуль Ecto.Changeset
с возможностью добавления предупреждений в набор изменений. Я хотел иметь функцию add_warnings/4
, которая добавляет предупреждение в набор изменений в виде простого списка предупреждений с этой структурой warnings: [{atom, {String.t, Keyword.t}}]
, похожей на errors
. Разница между поведением warnings
и errors
заключается в том, что при возникновении ошибки данные не сохраняются, а при возникновении предупреждения данные сохраняются.
Ecto.Changeset
структура расширена ключами warnings
и warningless?
:
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
Настроены функции экто для литья, изменения, обработки и т. Д. Добавлена функция add_warnings/4
:
@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
В результате я получаю changeset
с ожидаемыми ключами:
#Ecto.Changeset<action: nil, changes: %{}, data: #Company.Booking<>, errors: [],
valid?: true, warnings: [], warningless?: true>
Когда я вношу изменение с ошибкой и предупреждением, я получаю:
#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>
Итак, что касается предупреждений, все как и ожидалось. Затем, когда я вношу изменение с предупреждением, но без ошибки, я получаю:
#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>
Все как положено. Если я не вношу никаких изменений в форму, я все равно получаю предупреждение о номере телефона, но я получаю:
#Ecto.Changeset<action: nil, changes: %{}, data: #Company.Booking<>, errors: [],
valid?: true, warnings: [], warningless?: true>
Я получил набор изменений без каких-либо предупреждений, поскольку в наборе изменений нет ключа changes
, потому что данные не изменились.
Вопрос в следующем: как реализовать функциональность предупреждений, чтобы предупреждения всегда были в наборе изменений, даже если никаких изменений не было сделано?
Ecto.Changeset.get_field/3
вместо _ 2_ при добавлении предупреждения. Впрочем, какова в этом цель? Если вы захотите сохранить данные при предупреждении, вы потеряете набор изменений и не сможете показать пользователю сообщение. - person Justin Wood   schedule 23.06.2017