英文:
GORM .Save don't save "has one" relation to the database
问题
我有一个结构体:
type Book struct {
	gorm.Model
	Title       string      `json:"title"`
	Author      string      `json:"author"`
	Description string      `json:"description"`
	Category    string      `json:"Category"`
	Publisher   string      `json:"publisher"`
	AuthorsCard AuthorsCard `gorm:"foreignKey:BookID" json:"authorscard"`
}
type AuthorsCard struct {
	//gorm.Model   // 我故意不想使用 gorm.model  
	ID          uint   `gorm:"primarykey"`
	BookID      uint
	Name        string `json:"name"`
	Age         int    `json:"age"`
	YearOfBirth int    `json:"year"`
	Biography   string `json:"biography"`
}
我试图创建一个更新函数:
// controller.go
func UpdateBook(ctx *gin.Context) {
	enableCors(&ctx.Writer)
	id := ctx.Param("ID")
	var updateBook = &models.Book{}
	if err := ctx.BindJSON(updateBook); err != nil {
		ctx.AbortWithStatus(http.StatusBadRequest)
		log.Fatal(err)
	} else {
		repository.UpdateBook(updateBook, id)
		ctx.JSON(http.StatusOK, updateBook)
		log.Println(updateBook)
	}
}
//repository.go
func UpdateBook(updateBook *models.Book, ID string) {
	book, db := GetBookById(ID)
	if updateBook.Title != "" {
		book.Title = updateBook.Title
	}
	if updateBook.Author != "" {
		book.Author = updateBook.Author
	}
	if updateBook.Publisher != "" {
		book.Publisher = updateBook.Publisher
	}
	if updateBook.Description != "" {
		book.Description = updateBook.Description
	}
	if updateBook.Category != "" {
		book.Category = updateBook.Category
	}
	if updateBook.AuthorsCard.Name != "" {
		book.AuthorsCard.Name = updateBook.AuthorsCard.Name
	}
	if updateBook.AuthorsCard.Age != 0 {
		book.AuthorsCard.Age = updateBook.AuthorsCard.Age
	}
	if updateBook.AuthorsCard.YearOfBirth != 0 {
		book.AuthorsCard.YearOfBirth = updateBook.AuthorsCard.YearOfBirth
	}
	if updateBook.AuthorsCard.Biography != "" {
		book.AuthorsCard.Biography = updateBook.AuthorsCard.Biography
	}
	db.Save(&book)
    // 同样可以使用 db.Preload("AuthorsCard").Save(&book)
}
问题是:当我发出 PUT 请求时,我收到了完全更新的数据。当我尝试发出 GET 请求时,除了相关的 AuthorsCard 字段之外,所有字段都已更新。
PUT 响应:
200 状态码
{
    "ID": 0,
    "CreatedAt": "0001-01-01T00:00:00Z",
    "UpdatedAt": "0001-01-01T00:00:00Z",
    "DeletedAt": null,
    "title": "Test",
    "author": "author",
    "description": "something",
    "Category": "Category",
    "publisher": "PB",
    "authorscard": {
        "ID": 0,
        "BookID": 0,
        "name": "Updated",
        "age": 22,
        "year": 1999,
        "biography": "biography Updated"
    }
}
之后的 GET 响应:
[
    {
        "ID": 1,
        "CreatedAt": "2022-06-29T14:57:37.489639+03:00",
        "UpdatedAt": "2022-06-29T15:50:11.578724+03:00",
        "DeletedAt": null,
        "title": "Test",
        "author": "author",
        "description": "something",
        "Category": "Category",
        "publisher": "PB",
        "authorscard": {
            "ID": 1,
            "BookID": 1,
            "name": "test",
            "age": 23,
            "year": 1999,
            "biography": "23fdgsdddTEST"
        }
    }
]
如你所见,"authorscard" 没有改变。请问,有人可以告诉我我做错了什么吗?
英文:
I have struct:
type Book struct {
	gorm.Model
	Title       string      `json:"title"`
	Author      string      `json:"author"`
	Description string      `json:"description"`
	Category    string      `json:"Category"`
	Publisher   string      `json:"publisher"`
	AuthorsCard AuthorsCard `gorm:"foreignKey:BookID" json:"authorscard"`
}
type AuthorsCard struct {
	//gorm.Model   // I purposely Don't want to use gorm.model  
	ID          uint `gorm:"primarykey"`
	BookID      uint
	Name        string `json:"name"`
	Age         int    `json:"age"`
	YearOfBirth int    `json:"year"`
	Biography   string `json:"biography"`
}
And I'm trying to make update function:
// controller.go
func UpdateBook(ctx *gin.Context) {
	enableCors(&ctx.Writer)
	id := ctx.Param("ID")
	var updateBook = &models.Book{}
	if err := ctx.BindJSON(updateBook); err != nil {
		ctx.AbortWithStatus(http.StatusBadRequest)
		log.Fatal(err)
	} else {
		repository.UpdateBook(updateBook, id)
		ctx.JSON(http.StatusOK, updateBook)
		log.Println(updateBook)
	}
}
//repository.go
func UpdateBook(updateBook *models.Book, ID string) {
	book, db := GetBookById(ID)
	if updateBook.Title != "" {
		book.Title = updateBook.Title
	}
	if updateBook.Author != "" {
		book.Author = updateBook.Author
	}
	if updateBook.Publisher != "" {
		book.Publisher = updateBook.Publisher
	}
	if updateBook.Description != "" {
		book.Description = updateBook.Description
	}
	if updateBook.Category != "" {
		book.Category = updateBook.Category
	}
	if updateBook.AuthorsCard.Name != "" {
		book.AuthorsCard.Name = updateBook.AuthorsCard.Name
	}
	if updateBook.AuthorsCard.Age != 0 {
		book.AuthorsCard.Age = updateBook.AuthorsCard.Age
	}
	if updateBook.AuthorsCard.YearOfBirth != 0 {
		book.AuthorsCard.YearOfBirth = updateBook.AuthorsCard.YearOfBirth
	}
	if updateBook.AuthorsCard.Biography != "" {
		book.AuthorsCard.Biography = updateBook.AuthorsCard.Biography
	}
	db.Save(&book)
    // same with db.Preload("AuthorsCard").Save(&book)
}
The issue is: When I make an PUT request, I receive Fully updated data. And when I'm trying to make GET request all my fields, except related AuthorsCard, are been updated.
PUT response:
200 Code
{
    "ID": 0,
    "CreatedAt": "0001-01-01T00:00:00Z",
    "UpdatedAt": "0001-01-01T00:00:00Z",
    "DeletedAt": null,
    "title": "Test",
    "author": "author",
    "description": "something",
    "Category": "Category",
    "publisher": "PB",
    "authorscard": {
        "ID": 0,
        "BookID": 0,
        "name": "Updated",
        "age": 22,
        "year": 1999,
        "biography": "biography Updated"
    }
}
Get response after that:
[
    {
        "ID": 1,
        "CreatedAt": "2022-06-29T14:57:37.489639+03:00",
        "UpdatedAt": "2022-06-29T15:50:11.578724+03:00",
        "DeletedAt": null,
        "title": "Test",
        "author": "author",
        "description": "something",
        "Category": "Category",
        "publisher": "PB",
        "authorscard": {
            "ID": 1,
            "BookID": 1,
            "name": "test",
            "age": 23,
            "year": 1999,
            "biography": "23fdgsdddTEST"
        }
    }
]
As you can see "authorscard" hasn't changed. Please, can someone tell me what I'm doing wrong?
答案1
得分: 3
你需要明确告诉 Gorm 存储/更新关联关系。
db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&book)
英文:
You need to explicitly tell Gorm to store/update associations.
db.Session(&gorm.Session{FullSaveAssociations: true}).Updates(&book)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论