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 { | ||||
| 		schema.err = err | ||||
| 	} | ||||
| 	relation.JoinTable.Name = 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 | ||||
| 	relRefName := relation.FieldSchema.Name | ||||
| @ -290,36 +296,38 @@ func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Fiel | ||||
| 	} | ||||
| 
 | ||||
| 	// build references
 | ||||
| 	for idx, f := range relation.JoinTable.Fields { | ||||
| 		// use same data type for foreign keys
 | ||||
| 		f.DataType = fieldsMap[f.Name].DataType | ||||
| 		f.GORMDataType = fieldsMap[f.Name].GORMDataType | ||||
| 		relation.JoinTable.PrimaryFields[idx] = f | ||||
| 		ownPriamryField := schema == fieldsMap[f.Name].Schema && ownFieldsMap[f.Name] | ||||
| 	for _, f := range relation.JoinTable.Fields { | ||||
| 		if f.Creatable { | ||||
| 			// use same data type for foreign keys
 | ||||
| 			f.DataType = fieldsMap[f.Name].DataType | ||||
| 			f.GORMDataType = fieldsMap[f.Name].GORMDataType | ||||
| 			relation.JoinTable.PrimaryFields = append(relation.JoinTable.PrimaryFields, f) | ||||
| 			ownPriamryField := schema == fieldsMap[f.Name].Schema && ownFieldsMap[f.Name] | ||||
| 
 | ||||
| 		if ownPriamryField { | ||||
| 			joinRel := relation.JoinTable.Relationships.Relations[relName] | ||||
| 			joinRel.Field = relation.Field | ||||
| 			joinRel.References = append(joinRel.References, &Reference{ | ||||
| 				PrimaryKey: fieldsMap[f.Name], | ||||
| 				ForeignKey: f, | ||||
| 			}) | ||||
| 		} else { | ||||
| 			joinRefRel := relation.JoinTable.Relationships.Relations[relRefName] | ||||
| 			if joinRefRel.Field == nil { | ||||
| 				joinRefRel.Field = relation.Field | ||||
| 			if ownPriamryField { | ||||
| 				joinRel := relation.JoinTable.Relationships.Relations[relName] | ||||
| 				joinRel.Field = relation.Field | ||||
| 				joinRel.References = append(joinRel.References, &Reference{ | ||||
| 					PrimaryKey: fieldsMap[f.Name], | ||||
| 					ForeignKey: f, | ||||
| 				}) | ||||
| 			} else { | ||||
| 				joinRefRel := relation.JoinTable.Relationships.Relations[relRefName] | ||||
| 				if joinRefRel.Field == nil { | ||||
| 					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], | ||||
| 				ForeignKey: f, | ||||
| 
 | ||||
| 			relation.References = append(relation.References, &Reference{ | ||||
| 				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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu