【问题标题】:Ecto Changeset add functionality for warningsEcto Changeset 添加警告功能
【发布时间】:2017-06-23 09:32:08
【问题描述】:

我创建了一个 ecto 存储库的分支来扩展 Ecto.Changeset 模块,从而能够向变更集添加警告。我想要一个add_warnings/4 函数,它向变更集添加一个警告,作为具有此结构warnings: [{atom, {String.t, Keyword.t}}] 的简单警告列表,类似于errorswarningserrors 的行为区别在于,发生错误时不持久化数据,而当出现警告时,则持久化数据。

Ecto.Changeset 结构扩展了键 warningswarningless?:

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


【解决方案1】:

您应该考虑在您要创建的每个 changeset 函数的开头预先填写警告 - 因为您不能在那里使用 plug,您可以编写一个宏来为您处理此逻辑, 建议使用__using__,因此很容易将您的逻辑与 Ecto 的默认逻辑区分开来。

您的验证不应将警告添加到警告列表,但您必须以另一种方式实施它 - 如果该字段正常,您将从该列表中删除已经存在的警告。这样,您就可以确定您的变更集在 warningless 时没有问题,因为它从该列表中删除了所有警告,并且对于变更集中的空变更非常有效。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多