1

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.