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" | ||||||
| 	"gorm.io/gorm/clause" | 	"gorm.io/gorm/clause" | ||||||
|  | 	"gorm.io/gorm/schema" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func SaveBeforeAssociations(db *gorm.DB) { | func SaveBeforeAssociations(db *gorm.DB) { | ||||||
| @ -145,7 +146,7 @@ func SaveAfterAssociations(db *gorm.DB) { | |||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					db.AddError(db.Session(&gorm.Session{}).Clauses(clause.OnConflict{ | 					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), | 						DoUpdates: clause.AssignmentColumns(assignmentColumns), | ||||||
| 					}).Create(elems.Interface()).Error) | 					}).Create(elems.Interface()).Error) | ||||||
| 				} | 				} | ||||||
| @ -168,7 +169,7 @@ func SaveAfterAssociations(db *gorm.DB) { | |||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					db.AddError(db.Session(&gorm.Session{}).Clauses(clause.OnConflict{ | 					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), | 						DoUpdates: clause.AssignmentColumns(assignmentColumns), | ||||||
| 					}).Create(f.Interface()).Error) | 					}).Create(f.Interface()).Error) | ||||||
| 				} | 				} | ||||||
| @ -230,7 +231,7 @@ func SaveAfterAssociations(db *gorm.DB) { | |||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				db.AddError(db.Session(&gorm.Session{}).Clauses(clause.OnConflict{ | 				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), | 					DoUpdates: clause.AssignmentColumns(assignmentColumns), | ||||||
| 				}).Create(elems.Interface()).Error) | 				}).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" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
|  | 	. "gorm.io/gorm/utils/tests" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type Blog struct { | type Blog struct { | ||||||
| @ -410,3 +411,38 @@ func TestManyToManyWithCustomizedForeignKeys2(t *testing.T) { | |||||||
| 		t.Fatalf("EN Blog's tags should be cleared") | 		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