【发布时间】:2017-06-23 09:32:08
【问题描述】:
我创建了一个 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
调整了用于铸造、更改、处理参数等的 Ecto 功能。新增功能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而不是Ecto.Changeset.get_change/3。不过,这样做的目的是什么?如果您希望在警告时保留数据,您将丢失变更集并且无法向用户显示消息。
标签: functional-programming elixir phoenix-framework ecto extending