Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix replace associations with custom pk #7078

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion callbacks/associations.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@
} else if ref.PrimaryValue != "" {
db.AddError(ref.ForeignKey.Set(db.Statement.Context, f, ref.PrimaryValue))
}
assignmentColumns = append(assignmentColumns, ref.ForeignKey.DBName)

assignmentColumns = append(assignmentColumns, getAssignmentColumnsForForeignKey(ref.ForeignKey)...)
}

saveAssociations(db, rel, f, selectColumns, restricted, assignmentColumns)
Expand Down Expand Up @@ -431,6 +432,33 @@
return db.AddError(tx.Create(values).Error)
}

func getAssignmentColumnsForForeignKey(foreignKey *schema.Field) []string {
var assignmentColumns []string

Check failure on line 436 in callbacks/associations.go

View workflow job for this annotation

GitHub Actions / runner / golangci-lint

[golangci] reported by reviewdog 🐶 Consider pre-allocating `assignmentColumns` (prealloc) Raw Output: callbacks/associations.go:436:2: Consider pre-allocating `assignmentColumns` (prealloc) var assignmentColumns []string ^

if foreignKey.Schema == nil {
return assignmentColumns
}

if !foreignKey.PrimaryKey {
assignmentColumns = append(assignmentColumns, foreignKey.DBName)
return assignmentColumns
}

for _, field := range foreignKey.Schema.Fields {
if field.PrimaryKey {
continue
}

if field.DBName == "" {
continue
}

assignmentColumns = append(assignmentColumns, field.DBName)
}

return assignmentColumns
}

// check association values has been saved
// if values kind is Struct, check it has been saved
// if values kind is Slice/Array, check all items have been saved
Expand Down
40 changes: 35 additions & 5 deletions tests/associations_has_one_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,14 +256,44 @@ func TestPolymorphicHasOneAssociationForSlice(t *testing.T) {
AssertAssociationCount(t, pets, "Toy", 0, "After Clear")
}

func TestHasOneAssociationReplaceWithNonValidValue(t *testing.T) {
user := User{Name: "jinzhu", Account: Account{Number: "1"}}
func TestReplaceHasOneAssociationWithCustomPK(t *testing.T) {
if DB.Dialector.Name() == "sqlite" {
return
}

if err := DB.Create(&user).Error; err != nil {
DB.Migrator().DropTable(&Owner{})
DB.Migrator().DropTable(&CreditCard{})

DB.AutoMigrate(&CreditCard{})
DB.AutoMigrate(&Owner{})

owner := Owner{
Name: "jinzhu",
CreditCard: CreditCard{
Number: "123",
UserName: "jinzhu",
},
}

if err := DB.Create(&owner).Error; err != nil {
t.Fatalf("errors happened when create: %v", err)
}

if err := DB.Model(&user).Association("Languages").Replace(Account{Number: "2"}); err == nil {
t.Error("expected association error to be not nil")
wantNumber := "456"

if err := DB.Model(&owner).Association("CreditCard").Replace(&CreditCard{
Number: wantNumber,
UserName: "jinzhu",
}); err != nil {
t.Fatalf("errors happened when create: %v", err)
}

var result Owner
if err := DB.Preload("CreditCard").First(&result, owner.ID).Error; err != nil {
t.Fatalf("errors happened when getting credit card: %v", err)
}

if result.CreditCard.Number != wantNumber {
t.Fatal("wrong credit card number")
}
}
11 changes: 11 additions & 0 deletions utils/tests/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,14 @@ type Child struct {
ParentID *uint
Parent *Parent
}

type Owner struct {
gorm.Model
Name string `gorm:"index"`
CreditCard CreditCard `gorm:"foreignKey:OwnerName;references:name"`
}

type CreditCard struct {
Number string
UserName string `gorm:"primaryKey;unique;size:255"`
}
Loading