为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中增加结构值

在 Go 中增加结构值

Go
慕的地6264312 2022-07-11 16:43:35
我希望看到visits每个GET请求的增量,/foo但它仍然是1. 我在这里做错了什么?package mainimport (    "log"    "github.com/gofiber/fiber/v2"    "gorm.io/driver/sqlite"    "gorm.io/gorm")// Item modeltype Item struct {    gorm.Model    UID    int64  `gorm:"primaryKey;autoIncrement"`    Name   string `gorm:"index;not null"`    Visits int32  `gorm:"default 0"`}func main() {    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})    if err != nil {        panic(err)    }    db.AutoMigrate(&Item{})    db.Create(&Item{        Name: "foo",    })    app := fiber.New(fiber.Config{})    app.Get("/:name", func(c *fiber.Ctx) error {        var i Item        db.First(&i, "name = ?", c.Params("name"))        if i.Name == "" {            return c.Status(fiber.StatusNotFound).JSON(&fiber.Map{                "message": "Not found",            })        }        db.Model(&i).Update("visits", i.Visits+1)        return c.JSON(i)    })    log.Println("Listening...")    log.Fatal(app.Listen(":3000"))}
查看完整描述

1 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

如果您记录以下错误:


if err := db.Model(&i).Update("visits", i.Visits+1).Error; err != nil {

    fmt.Printf("update err != nil; %v\n", err)

}

你会看到它说:“需要条件”。所以,你可以像这样解决这个问题:


if err := db.Model(&i).Where("name = ?", i.Name).Update("visits", i.Visits+1).Error; err != nil {

    fmt.Printf("update err != nil; %v\n", err)

}

这是有关GORM 中的错误处理的更多详细信息


编辑:您的示例实际上存在一个更大的问题。问题是您将其定义UID为Item模型的一部分,这与提供的内容冲突gorm.Model。您可以在声明模型中看到以下模型定义:


// gorm.Model definition

type Model struct {

  ID        uint           `gorm:"primaryKey"`

  CreatedAt time.Time

  UpdatedAt time.Time

  DeletedAt gorm.DeletedAt `gorm:"index"`

}

当添加到您的Item类型/模型中时,您将获得:


type Item struct {

  // gorm.Model

  ID        uint           `gorm:"primaryKey"`

  CreatedAt time.Time

  UpdatedAt time.Time

  DeletedAt gorm.DeletedAt `gorm:"index"`

  // your fields

  UID    int64  `gorm:"primaryKey;autoIncrement"`

  Name   string `gorm:"index;not null"`

  Visits int32  `gorm:"default 0"`

}

似乎这会导致您的数据库表以奇怪的状态创建。您可能会在返回的 JSON 有效负载中注意到IDANDUID都等于 0。当您多次启动/停止服务器并查看创建的其他记录(因为您db.Create()位于顶部)时,您最终会得到多个项目名称为“foo”,所有的ID和UID都为 0...这就是为什么 GORM 在没有 WHERE 子句的情况下无法更新项目的原因,因为主键没有在表上正确设置。


如果您从模型中删除 UID(或者甚至只是从中删除“primaryKey”),则可以使用该Update()方法而无需 where 条件。因此,您的模型应如下所示:


// Item model

type Item struct {

    gorm.Model

    Name   string `gorm:"index;not null"`

    Visits int32  `gorm:"default 0"`

}

更改模型/类型后,请确保删除test.db文件,以便使用新/正确格式重新创建表。


最后,关于我的原始答案,您还应该看到 GORM 自动将错误记录到您的控制台,而无需像我建议的那样专门处理它们。


查看完整回答
反对 回复 2022-07-11
  • 1 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号