From 628a0ae707f230c67bca2e632fb302037c707705 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Mon, 15 Feb 2021 09:10:51 +0800 Subject: [PATCH] Fix foreign key & reference with same name, close #4081 --- schema/relationship.go | 20 ++++++++++++++++---- schema/relationship_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/schema/relationship.go b/schema/relationship.go index 0eaace89..1aa2d11a 100644 --- a/schema/relationship.go +++ b/schema/relationship.go @@ -81,7 +81,7 @@ func (schema *Schema) parseRelation(field *Field) *Relationship { } else { switch field.IndirectFieldType.Kind() { case reflect.Struct: - schema.guessRelation(relation, field, guessBelongs) + schema.guessRelation(relation, field, guessGuess) case reflect.Slice: schema.guessRelation(relation, field, guessHas) default: @@ -341,20 +341,32 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel type guessLevel int const ( - guessBelongs guessLevel = iota + guessGuess guessLevel = iota + guessBelongs guessEmbeddedBelongs guessHas guessEmbeddedHas ) -func (schema *Schema) guessRelation(relation *Relationship, field *Field, gl guessLevel) { +func (schema *Schema) guessRelation(relation *Relationship, field *Field, cgl guessLevel) { var ( primaryFields, foreignFields []*Field primarySchema, foreignSchema = schema, relation.FieldSchema + gl = cgl ) + if gl == guessGuess { + if field.Schema == relation.FieldSchema { + gl = guessBelongs + } else { + gl = guessHas + } + } + reguessOrErr := func() { - switch gl { + switch cgl { + case guessGuess: + schema.guessRelation(relation, field, guessBelongs) case guessBelongs: schema.guessRelation(relation, field, guessEmbeddedBelongs) case guessEmbeddedBelongs: diff --git a/schema/relationship_test.go b/schema/relationship_test.go index 64d0c2a7..a34777b7 100644 --- a/schema/relationship_test.go +++ b/schema/relationship_test.go @@ -433,3 +433,27 @@ func TestEmbeddedRelation(t *testing.T) { 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}, + }, + }, + ) +}