Your Question
I have the following structures
type Contact struct {
gorm.Model
Phone string `json:"phone_number,omitempty"`
Cellphone string `json:"cellphone,omitempty"`
Email string `json:"email,omitempty"`
Linkedin string `json:"linkedin,omitempty"`
Github string `json:"github,omitempty"`
Other json.RawMessage `json:"other,omitempty" gorm:"type:jsonb;default:'{}'"`
}
type User struct {
gorm.Model
FirstName string
// Foreign Keys
ContactID int64 `json:"contact_id"`
Contact Contact `json:"contact"`
}
Whenever I run something like this:
curl --location --request PATCH 'http://localhost:8080/users' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": 1,
"first_name": "David",
"contact": {
"id": 1,
"phone_number": "555-5551"
}
}'
I would expect something like this:
{
"ID": 1,
"first_name": "David", <--- Used to be John, so this is fine
"contact_id": 1,
"contact": {
"ID": 1,
"cellphone": "555-5550",
"phone_number": "555-5551" <---- Before the PATCH this was null
"email": "john@doe.com",
"linkedin": "http://www.linkedin.com/john-doe",
"other": "{test: test}"
}
}
But the result after running that PATCH:
{
"ID": 1,
"first_name": "David", <--- Used to be John, so this is fine
"contact_id": 1,
"contact": {
"ID": 1,
"phone_number": "555-5551",
"other": "{test: test}"
}
}
For some weird reason I lost cellphone, email and linkedin data...
Someone told me that I should do something like this:
type Contact struct {
gorm.Model
Phone string `json:"phone_number,omitempty"`
Cellphone string `json:"cellphone,omitempty"`
Email string `json:"email,omitempty"`
Linkedin string `json:"linkedin,omitempty"`
Github string `json:"github,omitempty"`
Other json.RawMessage `json:"other,omitempty" gorm:"type:jsonb;default:'{}'"`
UserID uint
}
type User struct {
gorm.Model
FirstName string
// Foreign Keys
ContactID int64 `json:"contact_id"`
Contact Contact `json:"contact"`
}
But this will create a one on one relation and I won't be able to create a User without a contact and that's no bueno, I need to be able to create a User without a contact.
On the server side I'm running the following go code:
r.db.GetDB().Session(&gorm.Session{FullSaveAssociations: true}).Updates(&user)
And I tried this as well:
r.db.GetDB().Preload("Contact").Updates(&user)
This is the debug result:
[1.818ms] [rows:1] UPDATE "schema"."users" SET "updated_at"='date',"first_name"='David',"contact_id"=1 WHERE "users"."deleted_at" IS NULL AND "id" = 1
Which is weird as well...
Edit: Debugging found this as well
[0.472ms] [rows:1] INSERT INTO "schema"."contacts" ("phone","cellphone","email","linkedin","github","created_at","updated_at","deleted_at","id") VALUES ('555-5551','','','','','2022-11-26 22:41:19.573','2022-11-26 22:41:19.573',NULL,1) ON CONFLICT ("id") DO UPDATE SET "updated_at"='2022-11-26 22:41:19.573',"phone"="excluded"."phone","cellphone"="excluded"."cellphone","email"="excluded"."email","linkedin"="excluded"."linkedin","github"="excluded"."github","deleted_at"="excluded"."deleted_at" RETURNING "other","id"
I don't know why that query is running... it should just update the values that changed instead of the whole struct
The document you expected this should be explained
https://gorm.io/docs/belongs_to.html
Expected answer
A solution lol