gorm icon indicating copy to clipboard operation
gorm copied to clipboard

Wrong foreignKey setup for multiple embedded belongs-to relations of same type

Open cstaud opened this issue 1 year ago • 4 comments

GORM Playground Link

https://github.com/go-gorm/playground/pull/672

Description

cnp from the playground PR

When using multiple embedded belongs-to relations only 1 database foreignKey is created. Expected: a foreignKey for each relation is created.

type Country struct {
	Name string `gorm:"primaryKey"`
}

type Address struct {
	CountryName string
	Country     Country
}

type Org struct {
	ID       int
	Address1 Address `gorm:"embedded;embeddedPrefix:address1_"`
	Address2 Address `gorm:"embedded;embeddedPrefix:address2_"`
}

In the above example there should be a foreignKey for address1 -> countries and a foreignKey address2 -> countries. gorm only creates one foreignKey fk_orgs_country => address2_country_name->countries

Hint:

  • the generated naming for the foreignKey should respect the fieldName with its path / parent struct, as both relations result in the same foreignKey name.
  • the relations are correctly detected as embedded and belongs-to, but result in only one entry in the relations map, this is due to the fact that only fieldName is used within this map
  • possible solution: consider using BindNames of the field for name generation

cstaud avatar Dec 15 '23 10:12 cstaud

Embedded is not used to define the relationship between data tables. In this example, only Address and Country have relationships. https://gorm.io/docs/preload.html#Embedded-Preloading

a631807682 avatar Dec 29 '23 08:12 a631807682

Embedded is not used to define the relationship between data tables. In this example, only Address and Country have relationships. https://gorm.io/docs/preload.html#Embedded-Preloading

Is it technically not possible or currently just not supported? I do not 100% get it but then it is not possible to have a proper go struct reflecting the above relation. Defining two times the same struct (Address) with different names would then work but result in dirty go code.

Do you have a suggestion how you could achieve such an relation with a proper model?

staust avatar Dec 29 '23 08:12 staust

Embedded is not used to define the relationship between data tables. In this example, only Address and Country have relationships. gorm.io/docs/preload.html#Embedded-Preloading

Is it technically not possible or currently just not supported? I do not 100% get it but then it is not possible to have a proper go struct reflecting the above relation. Defining two times the same struct (Address) with different names would then work but result in dirty go code.

Do you have a suggestion how you could achieve such an relation with a proper model?

It is not currently supported. One possible way is to define embedded and relationship at the same time, which may need to support more tags.

a631807682 avatar Dec 29 '23 08:12 a631807682

I guess this then also applies for https://github.com/go-gorm/gorm/issues/6750 as this is somehow related. Currently this makes things even worse as the association saving mode will always break the relation in the above example. I did some further investigation with a similar struct where you need to explicitly exclude the "country" from the parent struct "address" from saving.

I hope this gives a bit more context.

staust avatar Dec 29 '23 08:12 staust