fix: duplicated preload (#6948)

This commit is contained in:
yetone 2024-04-15 11:20:20 +08:00 committed by GitHub
parent 1e13fd7543
commit 9a61ef2af8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 43 additions and 14 deletions

View File

@ -75,7 +75,7 @@ func embeddedValues(embeddedRelations *schema.Relationships) []string {
names := make([]string, 0, len(embeddedRelations.Relations)+len(embeddedRelations.EmbeddedRelations)) names := make([]string, 0, len(embeddedRelations.Relations)+len(embeddedRelations.EmbeddedRelations))
for _, relation := range embeddedRelations.Relations { for _, relation := range embeddedRelations.Relations {
// skip first struct name // skip first struct name
names = append(names, strings.Join(relation.Field.BindNames[1:], ".")) names = append(names, strings.Join(relation.Field.EmbeddedBindNames[1:], "."))
} }
for _, relations := range embeddedRelations.EmbeddedRelations { for _, relations := range embeddedRelations.EmbeddedRelations {
names = append(names, embeddedValues(relations)...) names = append(names, embeddedValues(relations)...)

View File

@ -56,6 +56,7 @@ type Field struct {
Name string Name string
DBName string DBName string
BindNames []string BindNames []string
EmbeddedBindNames []string
DataType DataType DataType DataType
GORMDataType DataType GORMDataType DataType
PrimaryKey bool PrimaryKey bool
@ -112,6 +113,7 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
Name: fieldStruct.Name, Name: fieldStruct.Name,
DBName: tagSetting["COLUMN"], DBName: tagSetting["COLUMN"],
BindNames: []string{fieldStruct.Name}, BindNames: []string{fieldStruct.Name},
EmbeddedBindNames: []string{fieldStruct.Name},
FieldType: fieldStruct.Type, FieldType: fieldStruct.Type,
IndirectFieldType: fieldStruct.Type, IndirectFieldType: fieldStruct.Type,
StructField: fieldStruct, StructField: fieldStruct,
@ -403,6 +405,9 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
ef.Schema = schema ef.Schema = schema
ef.OwnerSchema = field.EmbeddedSchema ef.OwnerSchema = field.EmbeddedSchema
ef.BindNames = append([]string{fieldStruct.Name}, ef.BindNames...) ef.BindNames = append([]string{fieldStruct.Name}, ef.BindNames...)
if _, ok := field.TagSettings["EMBEDDED"]; ok || !fieldStruct.Anonymous {
ef.EmbeddedBindNames = append([]string{fieldStruct.Name}, ef.EmbeddedBindNames...)
}
// index is negative means is pointer // index is negative means is pointer
if field.FieldType.Kind() == reflect.Struct { if field.FieldType.Kind() == reflect.Struct {
ef.StructField.Index = append([]int{fieldStruct.Index[0]}, ef.StructField.Index...) ef.StructField.Index = append([]int{fieldStruct.Index[0]}, ef.StructField.Index...)

View File

@ -150,12 +150,12 @@ func (schema *Schema) setRelation(relation *Relationship) {
} }
// set embedded relation // set embedded relation
if len(relation.Field.BindNames) <= 1 { if len(relation.Field.EmbeddedBindNames) <= 1 {
return return
} }
relationships := &schema.Relationships relationships := &schema.Relationships
for i, name := range relation.Field.BindNames { for i, name := range relation.Field.EmbeddedBindNames {
if i < len(relation.Field.BindNames)-1 { if i < len(relation.Field.EmbeddedBindNames)-1 {
if relationships.EmbeddedRelations == nil { if relationships.EmbeddedRelations == nil {
relationships.EmbeddedRelations = map[string]*Relationships{} relationships.EmbeddedRelations = map[string]*Relationships{}
} }

View File

@ -121,6 +121,29 @@ func TestSelfReferentialBelongsToOverrideReferences(t *testing.T) {
}) })
} }
func TestBelongsToWithMixin(t *testing.T) {
type Profile struct {
gorm.Model
Refer string
Name string
}
type ProfileMixin struct {
Profile Profile `gorm:"References:Refer"`
ProfileRefer int
}
type User struct {
gorm.Model
ProfileMixin
}
checkStructRelation(t, &User{}, Relation{
Name: "Profile", Type: schema.BelongsTo, Schema: "User", FieldSchema: "Profile",
References: []Reference{{"Refer", "Profile", "ProfileRefer", "User", "", false}},
})
}
func TestHasOneOverrideForeignKey(t *testing.T) { func TestHasOneOverrideForeignKey(t *testing.T) {
type Profile struct { type Profile struct {
gorm.Model gorm.Model
@ -776,6 +799,10 @@ func TestEmbeddedBelongsTo(t *testing.T) {
type NestedAddress struct { type NestedAddress struct {
Address Address
} }
type CountryMixin struct {
CountryID int
Country Country
}
type Org struct { type Org struct {
ID int ID int
PostalAddress Address `gorm:"embedded;embeddedPrefix:postal_address_"` PostalAddress Address `gorm:"embedded;embeddedPrefix:postal_address_"`
@ -786,6 +813,7 @@ func TestEmbeddedBelongsTo(t *testing.T) {
Address Address
} }
NestedAddress *NestedAddress `gorm:"embedded;embeddedPrefix:nested_address_"` NestedAddress *NestedAddress `gorm:"embedded;embeddedPrefix:nested_address_"`
CountryMixin
} }
s, err := schema.Parse(&Org{}, &sync.Map{}, schema.NamingStrategy{}) s, err := schema.Parse(&Org{}, &sync.Map{}, schema.NamingStrategy{})
@ -815,15 +843,11 @@ func TestEmbeddedBelongsTo(t *testing.T) {
}, },
}, },
"NestedAddress": { "NestedAddress": {
EmbeddedRelations: map[string]EmbeddedRelations{ Relations: map[string]Relation{
"Address": { "Country": {
Relations: map[string]Relation{ Name: "Country", Type: schema.BelongsTo, Schema: "Org", FieldSchema: "Country",
"Country": { References: []Reference{
Name: "Country", Type: schema.BelongsTo, Schema: "Org", FieldSchema: "Country", {PrimaryKey: "ID", PrimarySchema: "Country", ForeignKey: "CountryID", ForeignSchema: "Org"},
References: []Reference{
{PrimaryKey: "ID", PrimarySchema: "Country", ForeignKey: "CountryID", ForeignSchema: "Org"},
},
},
}, },
}, },
}, },

View File

@ -466,7 +466,7 @@ func TestEmbedPreload(t *testing.T) {
}, },
}, { }, {
name: "nested address country", name: "nested address country",
preloads: map[string][]interface{}{"NestedAddress.EmbeddedAddress.Country": {}}, preloads: map[string][]interface{}{"NestedAddress.Country": {}},
expect: Org{ expect: Org{
ID: org.ID, ID: org.ID,
PostalAddress: EmbeddedAddress{ PostalAddress: EmbeddedAddress{