I think I found the reason for the missing errors on UI.
The model I am starting with is this one:
%Recenza.Models.Specialist{
__meta__: #Ecto.Schema.Metadata<:loaded, "specialists">,
id: 502,
description: nil,
title: nil,
facebook: nil,
twitter: nil,
instagram: nil,
website: nil,
phone: "0757220577",
registration_date: nil,
active: false,
company_name: nil,
employment_status: nil,
rating: nil,
reviews_count: nil,
user_id: 1002,
user: #Ecto.Association.NotLoaded<association :user is not loaded>,
address_id: nil,
address: nil,
speciality_id: nil,
speciality: nil,
gallery_id: nil,
gallery: #Ecto.Association.NotLoaded<association :gallery is not loaded>,
reviews: #Ecto.Association.NotLoaded<association :reviews is not loaded>,
services: [],
inserted_at: ~N[2024-01-06 14:25:58],
updated_at: ~N[2024-01-06 14:25:58]
}
As you can see the address association is empty at the moment.
The first change in the form calls “update” with these parameters:
%{
"address" => %{
"_persistent_id" => "0",
"city" => "",
"country" => "România",
"county" => "",
"lat" => "",
"lng" => "",
"street" => ""
},
"company_name" => "",
"description" => "",
"employment_status" => "employee",
"facebook" => "",
"instagram" => "",
"phone" => "0757220577",
"speciality" => %{
"_persistent_id" => "0",
"category_id" => "",
"id" => "",
"name" => "",
"name_text_input" => ""
},
"speciality_id" => "",
"user_id" => "1002",
"website" => ""
}
nested address comes as a new empty map.
which transforms the Specialist changeset into this:
AFTER ASSIGN: #Ecto.Changeset<
action: nil,
changes: %{
address: #Ecto.Changeset<
action: :insert,
changes: %{country: "România"},
errors: [
street: {"can't be blank", [validation: :required]},
city: {"can't be blank", [validation: :required]},
county: {"can't be blank", [validation: :required]}
],
data: #Recenza.Models.Address<>,
valid?: false
>,
employment_status: "employee",
speciality: #Ecto.Changeset<
action: :insert,
changes: %{},
errors: [
name: {"can't be blank", [validation: :required]},
category_id: {"can't be blank", [validation: :required]}
],
data: #Recenza.Models.Speciality<>,
valid?: false
>
},
errors: [
description: {"can't be blank", [validation: :required]},
speciality_id: {"can't be blank", [validation: :required]},
company_name: {"Compania este necesara pentru angajati", []}
],
data: #Recenza.Models.Specialist<>,
valid?: false
>
Address related model has been added in the changeset with the action :insert
If I submit the form now and print in the logs the changeset before submit and after Repo.insert I can see this:
CHANGESET BEFORE SAFE:
#Ecto.Changeset<
action: nil,
changes: %{
address: #Ecto.Changeset<
action: :insert,
changes: %{country: "România"},
errors: [
street: {"can't be blank", [validation: :required]},
city: {"can't be blank", [validation: :required]},
county: {"can't be blank", [validation: :required]}
],
data: #Recenza.Models.Address<>,
valid?: false
>,
employment_status: "employee",
speciality: #Ecto.Changeset<
action: :insert,
changes: %{},
errors: [
name: {"can't be blank", [validation: :required]},
category_id: {"can't be blank", [validation: :required]}
],
data: #Recenza.Models.Speciality<>,
valid?: false
>
},
errors: [
description: {"can't be blank", [validation: :required]},
speciality_id: {"can't be blank", [validation: :required]},
company_name: {"Compania este necesara pentru angajati", []}
],
data: #Recenza.Models.Specialist<>,
valid?: false
>
CHANGESET AFTER SAVE:
#Ecto.Changeset<
action: :update,
changes: %{
address: #Ecto.Changeset<
action: :insert,
changes: %{country: "România"},
errors: [
street: {"can't be blank", [validation: :required]},
city: {"can't be blank", [validation: :required]},
county: {"can't be blank", [validation: :required]}
],
data: #Recenza.Models.Address<>,
valid?: false
>,
employment_status: "employee",
speciality: #Ecto.Changeset<
action: :insert,
changes: %{},
errors: [
name: {"can't be blank", [validation: :required]},
category_id: {"can't be blank", [validation: :required]}
],
data: #Recenza.Models.Speciality<>,
valid?: false
>
},
errors: [
description: {"can't be blank", [validation: :required]},
speciality_id: {"can't be blank", [validation: :required]},
company_name: {"Compania este necesara pentru angajati", []}
],
data: #Recenza.Models.Specialist<>,
valid?: false
>
between those two changesets, for Specialist action has changed from nil to :update but for Address it’s the same :insert vs insert
For Phoenix nothing changed in the address fields to show errors, I guess.
The hack I found it works for now it’s like this. When computing the changeset for the initial form instead of this:
def job_data_changeset(specialist, attrs) when attrs == %{} do
change(specialist)
end
I have change it to this:
def job_data_changeset(specialist, attrs) when attrs == %{} do
specialist =
if is_nil(specialist.address) do
Map.put(specialist, :address, %Address{})
else
specialist
end
change(specialist)
end
It seems that for nested association I have to create an empty model when initializing the form.






















