mirror of https://github.com/go-gorm/gorm.git
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…
Reference in New Issue