mirror of https://github.com/go-gorm/gorm.git
Fix multiple M2M relations on one table, close #3347
This commit is contained in:
parent
0273856e4d
commit
162367be7d
|
@ -254,12 +254,18 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
joinTableFields = append(joinTableFields, reflect.StructField{
|
||||||
|
Name: schema.Name + field.Name,
|
||||||
|
Type: schema.ModelType,
|
||||||
|
Tag: `gorm:"-"`,
|
||||||
|
})
|
||||||
|
|
||||||
if relation.JoinTable, err = Parse(reflect.New(reflect.StructOf(joinTableFields)).Interface(), schema.cacheStore, schema.namer); err != nil {
|
if relation.JoinTable, err = Parse(reflect.New(reflect.StructOf(joinTableFields)).Interface(), schema.cacheStore, schema.namer); err != nil {
|
||||||
schema.err = err
|
schema.err = err
|
||||||
}
|
}
|
||||||
relation.JoinTable.Name = many2many
|
relation.JoinTable.Name = many2many
|
||||||
relation.JoinTable.Table = schema.namer.JoinTableName(many2many)
|
relation.JoinTable.Table = schema.namer.JoinTableName(many2many)
|
||||||
relation.JoinTable.PrimaryFields = make([]*Field, len(relation.JoinTable.Fields))
|
relation.JoinTable.PrimaryFields = make([]*Field, 0, len(relation.JoinTable.Fields))
|
||||||
|
|
||||||
relName := relation.Schema.Name
|
relName := relation.Schema.Name
|
||||||
relRefName := relation.FieldSchema.Name
|
relRefName := relation.FieldSchema.Name
|
||||||
|
@ -290,36 +296,38 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel
|
||||||
}
|
}
|
||||||
|
|
||||||
// build references
|
// build references
|
||||||
for idx, f := range relation.JoinTable.Fields {
|
for _, f := range relation.JoinTable.Fields {
|
||||||
// use same data type for foreign keys
|
if f.Creatable {
|
||||||
f.DataType = fieldsMap[f.Name].DataType
|
// use same data type for foreign keys
|
||||||
f.GORMDataType = fieldsMap[f.Name].GORMDataType
|
f.DataType = fieldsMap[f.Name].DataType
|
||||||
relation.JoinTable.PrimaryFields[idx] = f
|
f.GORMDataType = fieldsMap[f.Name].GORMDataType
|
||||||
ownPriamryField := schema == fieldsMap[f.Name].Schema && ownFieldsMap[f.Name]
|
relation.JoinTable.PrimaryFields = append(relation.JoinTable.PrimaryFields, f)
|
||||||
|
ownPriamryField := schema == fieldsMap[f.Name].Schema && ownFieldsMap[f.Name]
|
||||||
|
|
||||||
if ownPriamryField {
|
if ownPriamryField {
|
||||||
joinRel := relation.JoinTable.Relationships.Relations[relName]
|
joinRel := relation.JoinTable.Relationships.Relations[relName]
|
||||||
joinRel.Field = relation.Field
|
joinRel.Field = relation.Field
|
||||||
joinRel.References = append(joinRel.References, &Reference{
|
joinRel.References = append(joinRel.References, &Reference{
|
||||||
PrimaryKey: fieldsMap[f.Name],
|
PrimaryKey: fieldsMap[f.Name],
|
||||||
ForeignKey: f,
|
ForeignKey: f,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
joinRefRel := relation.JoinTable.Relationships.Relations[relRefName]
|
joinRefRel := relation.JoinTable.Relationships.Relations[relRefName]
|
||||||
if joinRefRel.Field == nil {
|
if joinRefRel.Field == nil {
|
||||||
joinRefRel.Field = relation.Field
|
joinRefRel.Field = relation.Field
|
||||||
|
}
|
||||||
|
joinRefRel.References = append(joinRefRel.References, &Reference{
|
||||||
|
PrimaryKey: fieldsMap[f.Name],
|
||||||
|
ForeignKey: f,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
joinRefRel.References = append(joinRefRel.References, &Reference{
|
|
||||||
PrimaryKey: fieldsMap[f.Name],
|
relation.References = append(relation.References, &Reference{
|
||||||
ForeignKey: f,
|
PrimaryKey: fieldsMap[f.Name],
|
||||||
|
ForeignKey: f,
|
||||||
|
OwnPrimaryKey: ownPriamryField,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
relation.References = append(relation.References, &Reference{
|
|
||||||
PrimaryKey: fieldsMap[f.Name],
|
|
||||||
ForeignKey: f,
|
|
||||||
OwnPrimaryKey: ownPriamryField,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -267,3 +267,34 @@ func TestMany2ManyWithMultiPrimaryKeys(t *testing.T) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMultipleMany2Many(t *testing.T) {
|
||||||
|
type Thing struct {
|
||||||
|
ID int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
ID int
|
||||||
|
Likes []Thing `gorm:"many2many:likes"`
|
||||||
|
Dislikes []Thing `gorm:"many2many:dislikes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
checkStructRelation(t, &Person{},
|
||||||
|
Relation{
|
||||||
|
Name: "Likes", Type: schema.Many2Many, Schema: "Person", FieldSchema: "Thing",
|
||||||
|
JoinTable: JoinTable{Name: "likes", Table: "likes"},
|
||||||
|
References: []Reference{
|
||||||
|
{"ID", "Person", "PersonID", "likes", "", true},
|
||||||
|
{"ID", "Thing", "ThingID", "likes", "", false},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Relation{
|
||||||
|
Name: "Dislikes", Type: schema.Many2Many, Schema: "Person", FieldSchema: "Thing",
|
||||||
|
JoinTable: JoinTable{Name: "dislikes", Table: "dislikes"},
|
||||||
|
References: []Reference{
|
||||||
|
{"ID", "Person", "PersonID", "dislikes", "", true},
|
||||||
|
{"ID", "Thing", "ThingID", "dislikes", "", false},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue