Fix associations using composite primary keys without ID field, close #3365
This commit is contained in:
		
							parent
							
								
									130f24090d
								
							
						
					
					
						commit
						fcb666cfa3
					
				| @ -5,6 +5,7 @@ import ( | ||||
| 
 | ||||
| 	"gorm.io/gorm" | ||||
| 	"gorm.io/gorm/clause" | ||||
| 	"gorm.io/gorm/schema" | ||||
| ) | ||||
| 
 | ||||
| func SaveBeforeAssociations(db *gorm.DB) { | ||||
| @ -145,7 +146,7 @@ func SaveAfterAssociations(db *gorm.DB) { | ||||
| 					} | ||||
| 
 | ||||
| 					db.AddError(db.Session(&gorm.Session{}).Clauses(clause.OnConflict{ | ||||
| 						Columns:   []clause.Column{{Name: rel.FieldSchema.PrioritizedPrimaryField.DBName}}, | ||||
| 						Columns:   onConflictColumns(rel.FieldSchema), | ||||
| 						DoUpdates: clause.AssignmentColumns(assignmentColumns), | ||||
| 					}).Create(elems.Interface()).Error) | ||||
| 				} | ||||
| @ -168,7 +169,7 @@ func SaveAfterAssociations(db *gorm.DB) { | ||||
| 					} | ||||
| 
 | ||||
| 					db.AddError(db.Session(&gorm.Session{}).Clauses(clause.OnConflict{ | ||||
| 						Columns:   []clause.Column{{Name: rel.FieldSchema.PrioritizedPrimaryField.DBName}}, | ||||
| 						Columns:   onConflictColumns(rel.FieldSchema), | ||||
| 						DoUpdates: clause.AssignmentColumns(assignmentColumns), | ||||
| 					}).Create(f.Interface()).Error) | ||||
| 				} | ||||
| @ -230,7 +231,7 @@ func SaveAfterAssociations(db *gorm.DB) { | ||||
| 				} | ||||
| 
 | ||||
| 				db.AddError(db.Session(&gorm.Session{}).Clauses(clause.OnConflict{ | ||||
| 					Columns:   []clause.Column{{Name: rel.FieldSchema.PrioritizedPrimaryField.DBName}}, | ||||
| 					Columns:   onConflictColumns(rel.FieldSchema), | ||||
| 					DoUpdates: clause.AssignmentColumns(assignmentColumns), | ||||
| 				}).Create(elems.Interface()).Error) | ||||
| 			} | ||||
| @ -310,3 +311,14 @@ func SaveAfterAssociations(db *gorm.DB) { | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func onConflictColumns(s *schema.Schema) (columns []clause.Column) { | ||||
| 	if s.PrioritizedPrimaryField != nil { | ||||
| 		return []clause.Column{{Name: s.PrioritizedPrimaryField.DBName}} | ||||
| 	} | ||||
| 
 | ||||
| 	for _, dbName := range s.PrimaryFieldDBNames { | ||||
| 		columns = append(columns, clause.Column{Name: dbName}) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| @ -6,6 +6,7 @@ import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"gorm.io/gorm" | ||||
| 	. "gorm.io/gorm/utils/tests" | ||||
| ) | ||||
| 
 | ||||
| type Blog struct { | ||||
| @ -410,3 +411,38 @@ func TestManyToManyWithCustomizedForeignKeys2(t *testing.T) { | ||||
| 		t.Fatalf("EN Blog's tags should be cleared") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestCompositePrimaryKeysAssociations(t *testing.T) { | ||||
| 	type Label struct { | ||||
| 		BookID *uint  `gorm:"primarykey"` | ||||
| 		Name   string `gorm:"primarykey"` | ||||
| 		Value  string | ||||
| 	} | ||||
| 
 | ||||
| 	type Book struct { | ||||
| 		ID     int | ||||
| 		Name   string | ||||
| 		Labels []Label | ||||
| 	} | ||||
| 
 | ||||
| 	DB.Migrator().DropTable(&Label{}, &Book{}) | ||||
| 	if err := DB.AutoMigrate(&Label{}, &Book{}); err != nil { | ||||
| 		t.Fatalf("failed to migrate") | ||||
| 	} | ||||
| 
 | ||||
| 	book := Book{ | ||||
| 		Name: "my book", | ||||
| 		Labels: []Label{ | ||||
| 			{Name: "region", Value: "emea"}, | ||||
| 		}, | ||||
| 	} | ||||
| 
 | ||||
| 	DB.Create(&book) | ||||
| 
 | ||||
| 	var result Book | ||||
| 	if err := DB.Preload("Labels").First(&result, book.ID).Error; err != nil { | ||||
| 		t.Fatalf("failed to preload, got error %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	AssertEqual(t, book, result) | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu