mirror of https://github.com/go-gorm/gorm.git
fix: duplicated preload (#6948)
This commit is contained in:
parent
1e13fd7543
commit
9a61ef2af8
|
@ -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)...)
|
||||||
|
|
|
@ -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...)
|
||||||
|
|
|
@ -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{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -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{
|
||||||
|
|
Loading…
Reference in New Issue