I would like to create a has-many association in GORM with a backreference using the owner's ID. When I create an association using the Append() method, the backreference gets filled in correctly. But when I delete the association, the owner ID remains set. Of course, it can be reset manually but it would be great if this was done automatically. I would like to test the existence of an association from the backward direction as well.
Here's a working example. I would expect UserID to be reset to zero after the call to Delete():
type Instance struct {
ID uint `gorm:"primarykey"`
Name string
UserID uint
}
type User struct {
ID uint `gorm:"primarykey"`
Name string
Instances []Instance
}
func TestOneToMany(t *testing.T) {
var err error
var db *gorm.DB
if db, err = gorm.Open(
sqlite.Open("file::memory:"),
&gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
},
); err != nil {
t.Fatalf("error connecting to test database: %s", err)
}
db.AutoMigrate(
&Instance{},
&User{},
)
var (
user = User{Name: "User Name"}
instance = Instance{Name: "Instance Name"}
tx *gorm.DB
)
if tx = db.Create(&user); tx.Error != nil {
t.Fatalf("user creation error: %s", tx.Error)
}
if tx = db.Create(&instance); tx.Error != nil {
t.Fatalf("instance creation error: %s", tx.Error)
}
printEm(&user, &instance)
if err = db.
Model(&user).
Association("Instances").
Append(&instance); err != nil {
t.Fatalf("error assigning token to user: %s", err)
}
printEm(&user, &instance)
if err = db.
Model(&user).
Association("Instances").
Delete(&instance); err != nil {
t.Fatalf("error removing association: %s", err)
}
printEm(&user, &instance)
if instance.UserID != 0 {
t.Fatal("expected user ID to be 0")
}
}
func printEm(user *User, instance *Instance) {
fmt.Printf("\nUser: %+v\nInstance: %+v\n\n", *user, *instance)
}