From e1b4c066a8bd3f8bca8d2f6fa141927776fca028 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Mon, 29 Nov 2021 11:02:32 +0800 Subject: [PATCH] Fix FullSaveAssociations, close #4874 --- callbacks/create.go | 3 +++ clause/set.go | 4 ++-- tests/associations_test.go | 28 ++++++++++++++++++++++++++++ tests/go.mod | 1 + tests/migrate_test.go | 2 +- utils/tests/models.go | 12 ++++++++++++ 6 files changed, 47 insertions(+), 3 deletions(-) diff --git a/callbacks/create.go b/callbacks/create.go index df774349..c585fbe9 100644 --- a/callbacks/create.go +++ b/callbacks/create.go @@ -317,6 +317,9 @@ func ConvertToCreateValues(stmt *gorm.Statement) (values clause.Values) { } onConflict.DoUpdates = append(onConflict.DoUpdates, clause.AssignmentColumns(columns)...) + if len(onConflict.DoUpdates) == 0 { + onConflict.DoNothing = true + } // use primary fields as default OnConflict columns if len(onConflict.Columns) == 0 { diff --git a/clause/set.go b/clause/set.go index 6a885711..75eb6bdd 100644 --- a/clause/set.go +++ b/clause/set.go @@ -24,9 +24,9 @@ func (set Set) Build(builder Builder) { builder.AddVar(builder, assignment.Value) } } else { - builder.WriteQuoted(PrimaryColumn) + builder.WriteQuoted(Column{Name: PrimaryKey}) builder.WriteByte('=') - builder.WriteQuoted(PrimaryColumn) + builder.WriteQuoted(Column{Name: PrimaryKey}) } } diff --git a/tests/associations_test.go b/tests/associations_test.go index 3b270625..a8d47886 100644 --- a/tests/associations_test.go +++ b/tests/associations_test.go @@ -176,3 +176,31 @@ func TestForeignKeyConstraintsBelongsTo(t *testing.T) { t.Fatalf("Should not find deleted profile") } } + +func TestFullSaveAssociations(t *testing.T) { + err := DB. + Session(&gorm.Session{FullSaveAssociations: true}). + Create(&Coupon{ + ID: "full-save-association-coupon1", + AppliesToProduct: []*CouponProduct{ + { + CouponId: "full-save-association-coupon1", + ProductId: "full-save-association-product1", + }, + }, + AmountOff: 10, + PercentOff: 0.0, + }).Error + + if err != nil { + t.Errorf("Failed, got error: %v", err) + } + + if DB.First(&Coupon{}, "id = ?", "full-save-association-coupon1").Error != nil { + t.Errorf("Failed to query saved coupon") + } + + if DB.First(&CouponProduct{}, "coupon_id = ? AND product_id = ?", "full-save-association-coupon1", "full-save-association-product1").Error != nil { + t.Errorf("Failed to query saved association") + } +} diff --git a/tests/go.mod b/tests/go.mod index 7e5ea8a5..36c7310c 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -4,6 +4,7 @@ go 1.14 require ( github.com/google/uuid v1.3.0 + github.com/jackc/pgtype v1.9.1 // indirect github.com/jackc/pgx/v4 v4.14.0 // indirect github.com/jinzhu/now v1.1.3 github.com/lib/pq v1.10.4 diff --git a/tests/migrate_test.go b/tests/migrate_test.go index 789a5e45..5cdf8e74 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -11,7 +11,7 @@ import ( ) func TestMigrate(t *testing.T) { - allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}} + allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}, &Coupon{}, &CouponProduct{}} rand.Seed(time.Now().UnixNano()) rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] }) DB.Migrator().DropTable("user_speaks", "user_friends", "ccc") diff --git a/utils/tests/models.go b/utils/tests/models.go index 8e833c93..5eee8468 100644 --- a/utils/tests/models.go +++ b/utils/tests/models.go @@ -60,3 +60,15 @@ type Language struct { Code string `gorm:"primarykey"` Name string } + +type Coupon struct { + ID string `gorm:"primarykey; size:255"` + AppliesToProduct []*CouponProduct `gorm:"foreignKey:CouponId;constraint:OnDelete:CASCADE"` + AmountOff uint32 `gorm:"amount_off"` + PercentOff float32 `gorm:"percent_off"` +} + +type CouponProduct struct { + CouponId string `gorm:"primarykey; size:255"` + ProductId string `gorm:"primarykey; size:255"` +}