GORM的.Save方法无法将”has one”关系保存到数据库中。

huangapple go评论97阅读模式
英文:

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)

huangapple
  • 本文由 发表于 2022年6月29日 21:11:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/72802007.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定