Suppose you have database models as follows:
package storage
type Country struct {
ID string `json:"id" gorm:"type:uuid"`
Name string `json:"name"`
Code string `json:"code"`
}
type City struct {
ID string `json:"id" gorm:"type:uuid"`
Name string `json:"name"`
Code *string `json:"code"`
CountryId string `json:"country_id"`
Country *Country `json:"country" gorm:"references:ID"`
IATA *string `json:"iata"`
Latitude *string `json:"latitude"`
Longitude *string `json:"longitude"`
}
The city should have a pointer to a Country model to make it easier to understand whether Country has been joined (in sql) or not (e.g. if city.Country == nil {panic("for whatever reason")}
)
The problem appears when I try to get the list of all cities:
package example
var cities []storage.City
tx.Joins("Country").Find(&cities)
Here, all the cities have been fetched from DB nicely, but the countries became the same in all the cities.
EXPECTED OUTPUT
[
{
ID:51e415ab-4301-4268-9345-deed6b1d72f6
Name:Bergen
Code:0xc0004d6ec0
CountryId:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Country:{
ID:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Name:Norwegen
Code:NO
}
SkyScannerId:0xc0004d6ee0
IATA:0xc0004d6ef0
Latitude:0xc0004d6f00
Longitude:0xc0004d6f10
},
{
ID:2468c7f0-0275-4bff-8b7e-4e87bfa63604
Name:Banská Bystrica
Code:0xc0004d6bc0
CountryId:00ba76d3-9591-4d45-a39d-f554375d790f
Country: {
ID:00ba76d3-9591-4d45-a39d-f554375d790f
Name:Slovakei
Code:SK
}
SkyScannerId:<nil>
IATA:<nil>
Latitude:0xc0004d6c00
Longitude:0xc0004d6c10
},
{
ID:75501988-3c80-4ef9-8081-73d20cbcc29b
Name:Prag
Code:0xc0004d6a60
CountryId:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6a90
IATA:0xc0004d6aa0
Latitude:0xc0004d6ac0
Longitude:0xc0004d6ad0
}
]
ACTUAL OUTPUT:
[
{
ID:51e415ab-4301-4268-9345-deed6b1d72f6
Name:Bergen
Code:0xc0004d6ec0
CountryId:0bd3890c-b6b7-4b27-8071-55c8f64562bb
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6ee0
IATA:0xc0004d6ef0
Latitude:0xc0004d6f00
Longitude:0xc0004d6f10
},
{
ID:2468c7f0-0275-4bff-8b7e-4e87bfa63604
Name:Banská Bystrica
Code:0xc0004d6bc0
CountryId:00ba76d3-9591-4d45-a39d-f554375d790f
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:<nil>
IATA:<nil>
Latitude:0xc0004d6c00
Longitude:0xc0004d6c10
},
{
ID:75501988-3c80-4ef9-8081-73d20cbcc29b
Name:Prag
Code:0xc0004d6a60
CountryId:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Country:{
ID:f4e819b2-5c1a-43f9-bfa1-fe56b6ee173e
Name:Tschechien
Code:CZ
}
SkyScannerId:0xc0004d6a90
IATA:0xc0004d6aa0
Latitude:0xc0004d6ac0
Longitude:0xc0004d6ad0
}
]
Please pay attention to Country field of the outputs. In the ACTUAL OUTPUT all the cities have the same country. I think this has something to do with the pointer.
I got EXPECTED OUTPUT when I removed the pointer from Country (so *Country
became Country
without *
). But I would like to get the same output with the pointer (*Country
).
Also, please do not pay attention to the values printed out in other fields. My main focus is the Country field.
Any ideas how to fix it ?
P.S. I know that i can survive without using the pointers too in the Country field, but I just want to know if there are any possibilities to do that.
CodePudding user response:
Try to put countryId as a pointer too.
Like this
CountryId *string `json:"country_id"`
Actually I tried to replicate the error with you code example, but it's working well.
CodePudding user response:
I have noticed that this is the behavior with gorm-v1.23.6
. Switching back to gorm-v1.23.5
solved the problem.