How do I reset GORM has-many backreference on delete?

50 views Asked by At

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)
}
0

There are 0 answers