如何在嵌套变更集上使用 add_error?
How to use add_error on a nested changeset?
根据我在documentation for add_error中的理解,它只能应用于顶级变更集。
如何在嵌套变更集上使用 add_error?
例如,采用这些模式:
defmodule MyApp.Person do
use Ecto.Schema
import Ecto.Changeset
schema "people" do
field :first_name, :string
field :last_name, :string
field :other_field_made_to_fail, :string
has_many :addresses, MyApp.Address
end
def changeset(person, attrs) do
person
|> cast(attrs, [:first_name, :last_name, :other_field_made_to_fail])
|> validate_required([:first_name, :last_name])
end
end
defmodule MyApp.Address do
use Ecto.Schema
import Ecto.Changeset
schema "addresses" do
field :street_name, :string
field :city, :string
field :state, :string
belongs_to :person, MyApp.Person
end
def changeset(address, attrs) do
address
|> cast(attrs, [:street_name, :city, :state])
|> validate_required([:city, :state])
|> cast_assoc(:person, with: &MyApp.Person.changeset/2, required: true)
end
end
并输入此数据:
%{
"address" => %{
"city" => "Test City",
"state" => "Test State",
"person" => %{
"first_name" => "John",
"last_name" => "Doe"
}
}
}
由此产生的变更集:
#Ecto.Changeset<
changes: %{
address: #Ecto.Changeset<
changes: %{
city: "Test City",
state: "Test State"
person: #Ecto.Changeset<
changes: %{
first_name: "John",
last_name: "Doe"
}
>
},
errors: []
valid?: true
>
}
>
如何使用 add_error/4
向嵌套 :person
属性内的 :other_field_made_to_fail
添加错误并保持变更集的其余部分完整?
我设法弄明白了。如果有其他人感兴趣,解决方案是在您的变更集上调用 update_change/3 并调用一个函数作为代表您的嵌套变更集的第三个参数:
Ecto.Changeset.update_change(changeset, :person, fn person_changeset ->
Ecto.Changeset.add_error(person_changeset, :other_field_made_to_fail, "error message here")
end)
最终结果是一个更新的 Address
变更集,其中现在包含 Person
变更集,其中有一个错误。
您还可以使用 update_change/3
对嵌套变更集执行其他变更集功能,它将 return 更新的嵌套变更集。
根据我在documentation for add_error中的理解,它只能应用于顶级变更集。
如何在嵌套变更集上使用 add_error?
例如,采用这些模式:
defmodule MyApp.Person do
use Ecto.Schema
import Ecto.Changeset
schema "people" do
field :first_name, :string
field :last_name, :string
field :other_field_made_to_fail, :string
has_many :addresses, MyApp.Address
end
def changeset(person, attrs) do
person
|> cast(attrs, [:first_name, :last_name, :other_field_made_to_fail])
|> validate_required([:first_name, :last_name])
end
end
defmodule MyApp.Address do
use Ecto.Schema
import Ecto.Changeset
schema "addresses" do
field :street_name, :string
field :city, :string
field :state, :string
belongs_to :person, MyApp.Person
end
def changeset(address, attrs) do
address
|> cast(attrs, [:street_name, :city, :state])
|> validate_required([:city, :state])
|> cast_assoc(:person, with: &MyApp.Person.changeset/2, required: true)
end
end
并输入此数据:
%{
"address" => %{
"city" => "Test City",
"state" => "Test State",
"person" => %{
"first_name" => "John",
"last_name" => "Doe"
}
}
}
由此产生的变更集:
#Ecto.Changeset<
changes: %{
address: #Ecto.Changeset<
changes: %{
city: "Test City",
state: "Test State"
person: #Ecto.Changeset<
changes: %{
first_name: "John",
last_name: "Doe"
}
>
},
errors: []
valid?: true
>
}
>
如何使用 add_error/4
向嵌套 :person
属性内的 :other_field_made_to_fail
添加错误并保持变更集的其余部分完整?
我设法弄明白了。如果有其他人感兴趣,解决方案是在您的变更集上调用 update_change/3 并调用一个函数作为代表您的嵌套变更集的第三个参数:
Ecto.Changeset.update_change(changeset, :person, fn person_changeset ->
Ecto.Changeset.add_error(person_changeset, :other_field_made_to_fail, "error message here")
end)
最终结果是一个更新的 Address
变更集,其中现在包含 Person
变更集,其中有一个错误。
您还可以使用 update_change/3
对嵌套变更集执行其他变更集功能,它将 return 更新的嵌套变更集。