Ecto Changeset添加警告功能

时间:2017-06-23 09:32:09

标签: functional-programming elixir phoenix-framework ecto extending

我创建了一个ecto存储库的分支,以扩展Ecto.Changeset模块,并能够向变更集添加警告。我希望有一个add_warnings/4函数,它会将变更集的警告添加为具有此结构warnings: [{atom, {String.t, Keyword.t}}]的警告的简单列表,类似于errorswarningserrors的行为之间的区别在于,当发生错误时,数据不会保留,但是当发生警告时,数据会保持不变。

使用键Ecto.Changesetwarnings扩展

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密钥,因为数据没有变化。

问题如下,即使没有做出任何更改,如何实现警告功能以在变更集中始终有警告?

1 个答案:

答案 0 :(得分:0)

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

您的验证不应该向警告列表添加警告,但您必须以另一种方式实现 - 如果字段正常,您将从此列表中删除已存在的警告。这样你就可以确定你的变更集在warningless时是正常的,因为它删除了此列表中的所有警告,并且它可以完美地用于变更集中的空变化。