Reputation: 9381
From what I understand in the documentation for add_error, It can only apply to the top-level changeset.
How do I use add_error on a nested changeset though?
For example, take these schemas:
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
And take this data input:
%{
"address" => %{
"city" => "Test City",
"state" => "Test State",
"person" => %{
"first_name" => "John",
"last_name" => "Doe"
}
}
}
And this resulting changeset:
#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
>
}
>
How would I use add_error/4
to add an error to :other_field_made_to_fail
inside the nested :person
attribute and keep the rest of the changeset intact?
Upvotes: 1
Views: 938
Reputation: 9381
I managed to figure it out. In case there are other people who are interested, the solution is to call update_change/3 on your changeset and call a function as the 3rd argument which represents your nested changeset:
Ecto.Changeset.update_change(changeset, :person, fn person_changeset ->
Ecto.Changeset.add_error(person_changeset, :other_field_made_to_fail, "error message here")
end)
The end result is an updated Address
changeset that now includes the Person
changeset with an error on it.
You can also use update_change/3
to do other changeset functions into your nested changesets and it will return the updated nested changeset.
Upvotes: 3