fixed belongs_to & has_one reversed if field same (proper fix) (#4694)

* fixed belongs_to & has_one reversed if field same

* hasmany same foreign key bug fixed and test added

* belongsToSameForeignKey fixed and reverted old fix
This commit is contained in:
Paras Waykole 2021-10-08 08:29:55 +05:30 committed by GitHub
parent 57d927d046
commit 5d91ddac8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 24 deletions

View File

@ -7,7 +7,6 @@ import (
"github.com/jinzhu/inflection" "github.com/jinzhu/inflection"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"gorm.io/gorm/utils"
) )
// RelationshipType relationship type // RelationshipType relationship type
@ -78,6 +77,8 @@ func (schema *Schema) parseRelation(field *Field) *Relationship {
schema.buildPolymorphicRelation(relation, field, polymorphic) schema.buildPolymorphicRelation(relation, field, polymorphic)
} else if many2many := field.TagSettings["MANY2MANY"]; many2many != "" { } else if many2many := field.TagSettings["MANY2MANY"]; many2many != "" {
schema.buildMany2ManyRelation(relation, field, many2many) schema.buildMany2ManyRelation(relation, field, many2many)
} else if belongsTo := field.TagSettings["BELONGSTO"]; belongsTo != "" {
schema.guessRelation(relation, field, guessBelongs)
} else { } else {
switch field.IndirectFieldType.Kind() { switch field.IndirectFieldType.Kind() {
case reflect.Struct: case reflect.Struct:
@ -405,14 +406,11 @@ func (schema *Schema) guessRelation(relation *Relationship, field *Field, cgl gu
if len(relation.foreignKeys) > 0 { if len(relation.foreignKeys) > 0 {
for _, foreignKey := range relation.foreignKeys { for _, foreignKey := range relation.foreignKeys {
ff := foreignSchema.LookUpField(foreignKey) if f := foreignSchema.LookUpField(foreignKey); f != nil {
pf := primarySchema.LookUpField(foreignKey) foreignFields = append(foreignFields, f)
isKeySame := utils.ExistsIn(foreignKey, &relation.primaryKeys) } else {
if ff == nil || (pf != nil && ff != nil && schema == primarySchema && primarySchema != foreignSchema && !isKeySame && field.IndirectFieldType.Kind() == reflect.Struct) {
reguessOrErr() reguessOrErr()
return return
} else {
foreignFields = append(foreignFields, ff)
} }
} }
} else { } else {

View File

@ -144,6 +144,25 @@ func TestHasOneOverrideReferences(t *testing.T) {
}) })
} }
func TestHasOneOverrideReferences2(t *testing.T) {
type Profile struct {
gorm.Model
Name string
}
type User struct {
gorm.Model
ProfileID uint `gorm:"column:profile_id"`
Profile *Profile `gorm:"foreignKey:ID;references:ProfileID"`
}
checkStructRelation(t, &User{}, Relation{
Name: "Profile", Type: schema.HasOne, Schema: "User", FieldSchema: "Profile",
References: []Reference{{"ProfileID", "User", "ID", "Profile", "", true}},
})
}
func TestHasOneWithOnlyReferences(t *testing.T) { func TestHasOneWithOnlyReferences(t *testing.T) {
type Profile struct { type Profile struct {
gorm.Model gorm.Model
@ -483,22 +502,47 @@ func TestSameForeignKey(t *testing.T) {
) )
} }
func TestBelongsToWithSameForeignKey(t *testing.T) { func TestBelongsToSameForeignKey(t *testing.T) {
type User struct {
gorm.Model
Name string
UUID string
}
type UserAux struct {
gorm.Model
Aux string
UUID string
User User `gorm:"ForeignKey:UUID;references:UUID;belongsTo"`
}
checkStructRelation(t, &UserAux{},
Relation{
Name: "User", Type: schema.BelongsTo, Schema: "UserAux", FieldSchema: "User",
References: []Reference{
{"UUID", "User", "UUID", "UserAux", "", false},
},
},
)
}
func TestHasOneWithSameForeignKey(t *testing.T) {
type Profile struct { type Profile struct {
gorm.Model gorm.Model
Name string Name string
ProfileRefer int ProfileRefer int // not used in relationship
} }
type User struct { type User struct {
gorm.Model gorm.Model
Profile Profile `gorm:"ForeignKey:ProfileRefer"` Profile Profile `gorm:"ForeignKey:ID;references:ProfileRefer"`
ProfileRefer int ProfileRefer int
} }
checkStructRelation(t, &User{}, Relation{ checkStructRelation(t, &User{}, Relation{
Name: "Profile", Type: schema.BelongsTo, Schema: "User", FieldSchema: "Profile", Name: "Profile", Type: schema.HasOne, Schema: "User", FieldSchema: "Profile",
References: []Reference{{"ID", "Profile", "ProfileRefer", "User", "", false}}, References: []Reference{{"ProfileRefer", "User", "ID", "Profile", "", true}},
}) })
} }

View File

@ -114,15 +114,3 @@ func ToString(value interface{}) string {
} }
return "" return ""
} }
func ExistsIn(a string, list *[]string) bool {
if list == nil {
return false
}
for _, b := range *list {
if b == a {
return true
}
}
return false
}