简体   繁体   English

在使用 GORM + Postgres + Go Gin + Graphql 创建之前自动生成 UUID

[英]Auto generate UUID before create with GORM + Postgres + Go Gin + Graphql

Is there any way to auto generate UUID with GORM while saving the object in DB in go?有什么方法可以在 go 的数据库中保存 object 的同时使用 GORM 自动生成 UUID?

I am having experience with ROR migrations, where ID would be auto generated and PK by default.我有 ROR 迁移的经验,默认情况下会自动生成 ID 和 PK。

Here is my code这是我的代码

Todo.go Todo.go

package model

type Todo struct {
    ID     string `json:"id"`
    Text   string `json:"text"`
    Done   bool   `json:"done"`
}

schema.resolvers.go架构.resolvers.go

func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) {
    db, _ := database.connect()
    defer db.Close()

    todo := &model.Todo{
        Text:   input.Text,
        ID:     fmt.Sprintf("%d", rand.Int()),  // I don't want to provide ID like this
    }
    db.Create(&todo)
    ...
}

models_gen.go models_gen.go

# GraphQL schema example
#
# https://gqlgen.com/getting-started/

type Todo {
  id: ID!
  text: String!
  done: Boolean!
}

input NewTodo {
  text: String!
  userId: String!
}


type Mutation {
  createTodo(input: NewTodo!): Todo!
}

Any help would be really appreciated.任何帮助将非常感激。

Assuming you're using gorm v2, you can use hooks to achieve this.假设您使用的是 gorm v2,您可以使用hooks来实现这一点。 The documentation about hooks is here关于钩子的文档在这里

In particular, you can have a look at the BeforeCreate hook.特别是,您可以查看BeforeCreate钩子。 Applied on a model , it provides a container for a function to be run before the creation in the database as its name state.应用于model ,它提供了一个容器,用于在数据库中创建之前运行的函数作为其名称状态。

The GORM documentation also provides an example to generate a UUID when we create a user entity in a database with Gorm, which seems to be what you're looking for: GORM 文档还提供了一个示例,用于在我们使用 Gorm 在数据库中创建用户实体时生成 UUID,这似乎是您要查找的内容:

func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
  u.UUID = uuid.New()

  if !u.IsValid() {
    err = errors.New("can't save invalid data")
  }
  return
}

GORM Hooks is the most obvious solution to generate UUID when creating an object. GORM Hooks是创建 object 时生成 UUID 的最明显的解决方案。

func (t *Todo) BeforeCreate(tx *gorm.DB) (err error) {
    t.ID = uuid.New().String()
    return
}

But if you want to generate UUID for every object, you could define a base struct and embed it into object structs.但是如果你想为每个 object 生成 UUID,你可以定义一个基本结构并将它嵌入到 object 结构中。

type Base struct {
    ID string `json:"id"`
}

func (b *Base) BeforeCreate(tx *gorm.DB) (err error) {
    b.ID = uuid.New().String()
    return
}

type Todo struct {
    Base
    Text string `json:"text"`
    Done bool   `json:"done"`
}

type User struct {
    Base
    Name string `json:"name"`
}

Or just use the GORM plugin next to generate UUID for objects.或者直接使用GORM插件为对象生成 UUID。

import "github.com/invzhi/next"

plugin := NewPlugin()
// register uuid generate function
plugin.Register("uuid", func(_, zero bool) (interface{}, error) {
    if !zero {
        return nil, SkipField
    }
    return uuid.New().String()
})

_ = db.Use(plugin)

type Todo struct {
    ID   string `gorm:"type:varchar(20);column:id;next:uuid"` // next:uuid meaning generate uuid when create
    Text string `gorm:"type:varchar(100);column:text`
    Done bool   `gorm:"type:boolean;column:done`
}

type User struct {
    ID   string `gorm:"type:varchar(20);column:id;next:uuid"` // next:uuid meaning generate uuid when create
    Name string `gorm:"type:varchar(100);column:name"`
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM