6

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

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 

外生功能用于铸造,改变处理参数,可以等调整。功能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关键没有改变。

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

+0

您没有显示任何更改集功能。大概你想要做的就是使用['Ecto.Changeset.get_field/3'](https://hexdocs.pm/ecto/Ecto.Changeset.html#get_field/3)而不是['Ecto.Changeset.get_change /3'](https://hexdocs.pm/ecto/Ecto.Changeset.html#get_change/3)添加警告时。虽然,这是什么目的?如果您想要将数据保留在警告状态,您将失去更改集并且无法向用户显示消息。 –

回答

0

你应该考虑在你创建的每个changeset功能的最开始预填的警告 - 因为你不能使用plug那里你可以拿出来写一个宏,将处理这个逻辑你,__using__是建议,因此将您的逻辑与Ecto的默认逻辑区分开来很容易。

您的验证不应该将警告添加到警告列表中,但您必须以另一种方式实施它 - 如果该字段没问题,则会从此列表中删除已存在的警告。这样,您可以肯定,当您的更改集为warningless时,它可以正常工作,因为它从该列表中删除了所有警告,并且对于更改集中的空白更改完全适用。