I have the following related tables:
type Person struct {
ID uint64 `json:"id" gorm:"primary_key;auto_increment"`
Name string `json:"name"`
Surname string `json:"surname"`
}
type Book struct {
ID uint64 `json:"id" gorm:"primary_key;auto_increment"`
Title string `json:"title" binding:"required,min=2,max=100" gorm:"type:varchar(100)"`
Author Person `json:"author" binding:"required" gorm:"foreignkey:AuthorID"` // * here
AuthorID uint64 `json:"-"` // * here
WrittenIn string `json:"written_in" gorm:"type:varchar(5)"`
CreatedAt time.Time `json:"created_at" gorm:"default:CURRENT_TIMESTAMP"`
UpdatedAt time.Time `json:"updated_at" gorm:"default:CURRENT_TIMESTAMP"`
}
I can successfully create data with Create()
method of gorm
using this function:
func CreateBook(ctx *gin.Context) {
// validating input
var inputData CreateBookInput
if err := ctx.ShouldBindJSON(&inputData); err != nil {
ctx.JSON(401, gin.H{"status": "fail", "error": err.Error()})
}
// create book
book := models.Book{Title: inputData.Title, AuthorID: inputData.AuthorID, WrittenIn: inputData.WrittenIn}
database.DB.Create(&book).Preload("Author")
// database.DB.Preload("Author").Create(&book)
// database.DB.Set("gorm:auto_preload", true).Create(&book)
ctx.JSON(201, gin.H{"status": "success", "book": book})
}
I want to return the newly created book with its author. Expected response:
"book": {
"id": 10,
"title": "Chinor ostidagi duel",
"author": {
"id": 3,
"name": "John",
"surname": "Smith"
},
"written_in": "1983",
"created_at": "2022-01-07T17:07:50.84473824+05:00",
"updated_at": "2022-01-07T17:07:50.84473824+05:00"
}
But I couldn't find a way to populate related 'author'. So what I get is:
"book": {
"id": 10,
"title": "Chinor ostidagi duel",
"author": {
"id": 0, // empty
"name": "", // empty
"surname": "" // empty
},
"written_in": "1983",
"created_at": "2022-01-07T17:07:50.84473824+05:00",
"updated_at": "2022-01-07T17:07:50.84473824+05:00"
}
Itried these methods with no success:
database.DB.Create(&book).Preload("Author")
database.DB.Preload("Author").Create(&book)
database.DB.Set("gorm:auto_preload", true).Create(&book)
database.DB.Create(&book).Set("gorm:auto_preload", true)
How can I populate related field of newly created data?
One possible solution that you could try is to use the AfterCreate
hook.
func (b *Book) AfterCreate(tx *gorm.DB) (err error) {
return tx.Model(b).Preload("Author").Error
}
You can find more info about hooks here.