0

我希望看到visits每个GET请求的增量,/foo但它仍然是1. 我在这里做错了什么?

package main

import (
    "log"

    "github.com/gofiber/fiber/v2"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

// Item model
type 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"))
}
4

1 回答 1

1

如果您记录以下错误:

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 中的错误处理的更多详细信息


编辑:您的示例实际上存在一个更大的问题。问题是您将其定义UIDItem模型的一部分,这与提供的内容冲突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”,所有的IDUID为 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 自动将错误记录到您的控制台,而无需像我建议的那样专门处理它们。

于 2020-11-09T21:55:22.277 回答