binary01
binary01

Reputation: 1898

gorm how to do insert with a has one relation that already exists

package main

import (
    "time"

    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
)

type Country struct {
    ID        int
    Name      string `gorm:"uniqueIndex"`
    CreatedAt time.Time
    UpdatedAt time.Time
}
type Operator struct {
    ID        int
    CountryID int
    Country   Country
    Name      string
    Code      string
    CreatedAt time.Time
    UpdatedAt time.Time
}

func main() {
    config := gorm.Config{
        Logger: logger.Default.LogMode(logger.Info),
    }
    db, err := gorm.Open(sqlite.Open("test.db"), &config)

    if err != nil {
        panic(err)
    }

    db.AutoMigrate(&Country{}, &Operator{})
    test1 := Operator{Country: Country{Name: "Test"}, Name: "Test1", Code: "A"}
    db.Create(&test1)

    test2 := Operator{Country: Country{Name: "Test"}, Name: "Test2", Code: "B"}
    db.Create(&test2)

}

With the above code, test1 creates a new Country and Operator and the operator_id is correct in the xqlite database.

With test2 however, operator_id is set to 0. What should I do to create the test2 entry and have it refer to an existing Country ?

Upvotes: 1

Views: 1274

Answers (1)

bluebunny
bluebunny

Reputation: 315

Your call to db.Create(&test2) is likely failing due to the uniqueIndex constraint on Country. Make sure to check your errors!

What you may find to work is to insert a single Country entry into the DB first, like so:

testCountry := Country{Name: "Test"}

if result := db.Create(&testCountry); result.Error != nil {
  // do something with result.Error
}

Based on my most recent experience working with Gorm, db.Create will populate testCountry.ID assuming it succeeds (always check your errors!). After that, create test1 and test2 like so:

test1 := Operator{
  Country:   testCountry,
  CountryID: testCountry.ID,
  Name:      "Test1", 
  Code:      "A",
}

if result := db.Create(&test1); result.Error != nil {
  // do something with result.Error
}

[... do the same thing with test2 ...]

Upvotes: 1

Related Questions