Fix foreign key & reference with same name, close #4081

This commit is contained in:
Jinzhu 2021-02-15 09:10:51 +08:00
parent 5744e29fbd
commit 628a0ae707
2 changed files with 40 additions and 4 deletions

View File

@ -81,7 +81,7 @@ func (schema *Schema) parseRelation(field *Field) *Relationship {
} else { } else {
switch field.IndirectFieldType.Kind() { switch field.IndirectFieldType.Kind() {
case reflect.Struct: case reflect.Struct:
schema.guessRelation(relation, field, guessBelongs) schema.guessRelation(relation, field, guessGuess)
case reflect.Slice: case reflect.Slice:
schema.guessRelation(relation, field, guessHas) schema.guessRelation(relation, field, guessHas)
default: default:
@ -341,20 +341,32 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel
type guessLevel int type guessLevel int
const ( const (
guessBelongs guessLevel = iota guessGuess guessLevel = iota
guessBelongs
guessEmbeddedBelongs guessEmbeddedBelongs
guessHas guessHas
guessEmbeddedHas guessEmbeddedHas
) )
func (schema *Schema) guessRelation(relation *Relationship, field *Field, gl guessLevel) { func (schema *Schema) guessRelation(relation *Relationship, field *Field, cgl guessLevel) {
var ( var (
primaryFields, foreignFields []*Field primaryFields, foreignFields []*Field
primarySchema, foreignSchema = schema, relation.FieldSchema primarySchema, foreignSchema = schema, relation.FieldSchema
gl = cgl
) )
if gl == guessGuess {
if field.Schema == relation.FieldSchema {
gl = guessBelongs
} else {
gl = guessHas
}
}
reguessOrErr := func() { reguessOrErr := func() {
switch gl { switch cgl {
case guessGuess:
schema.guessRelation(relation, field, guessBelongs)
case guessBelongs: case guessBelongs:
schema.guessRelation(relation, field, guessEmbeddedBelongs) schema.guessRelation(relation, field, guessEmbeddedBelongs)
case guessEmbeddedBelongs: case guessEmbeddedBelongs:

View File

@ -433,3 +433,27 @@ func TestEmbeddedRelation(t *testing.T) {
t.Fatalf("expects created by relations, but not found") t.Fatalf("expects created by relations, but not found")
} }
} }
func TestSameForeignKey(t *testing.T) {
type UserAux struct {
gorm.Model
Aux string
UUID string
}
type User struct {
gorm.Model
Name string
UUID string
Aux *UserAux `gorm:"foreignkey:UUID;references:UUID"`
}
checkStructRelation(t, &User{},
Relation{
Name: "Aux", Type: schema.HasOne, Schema: "User", FieldSchema: "UserAux",
References: []Reference{
{"UUID", "User", "UUID", "UserAux", "", true},
},
},
)
}