Below is a program (based on GORM) that defines two database tables (users
and cards
) with the logic of a user having one card. It then creates the database, fills it in, searches and prints out the only record in it.
My problem: the card in the ultimate search is empty, it is not attached to the user.
From the database perspective everything is OK:
SELECT * FROM users
id name card_id
1 john 1
SELECT * FROM cards
id number
1 42
Please note that card_id
in the first result correctly points to the id
of the card.
Why is my last search returning an empty card?
package main
import (
"fmt"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type User struct {
ID uint
Name string
Card Card
CardID uint
}
type Card struct {
ID uint
Number string
}
func main() {
// initialize the database
db, _ := gorm.Open(sqlite.Open("mytest.sqlite"), &gorm.Config{})
db.AutoMigrate(&User{}, &Card{})
// create one card
db.Create(&Card{
Number: "42",
})
// find that card
var myCard Card
db.Where(map[string]interface{}{"number": "42"}).First(&myCard)
// create a user with that card
db.Create(&User{
Name: "john",
Card: myCard,
})
// find that user
var myUser User
db.Where(map[string]interface{}{"name": "john"}).First(&myUser)
// print his name and card number
// the problem is here: the card number is empty, as if the card was not linked
fmt.Printf("name: %v, number: %v", myUser.Name, myUser.Card.Number)
}
// output
// name: john, number:
CodePudding user response:
go-gorm
will not load nested objects out of the box and automatically, you will have to specify that you want nested objects loaded. In your case, Card
is a nested object of User
. Here you can see more details on how to do that with the Preload
function, but it should look something like this:
var myUser User
db.Preload("Card").Where(map[string]interface{}{"name": "john"}).First(&myUser)