【问题标题】:How to Add Choices to database field using GORM如何使用 GORM 将选项添加到数据库字段
【发布时间】:2021-08-16 15:28:59
【问题描述】:

我对 Golang 很陌生,因为我主要使用 Python 编写代码,所以遇到了一个我无法解决的问题。我想通过GORM 或任何其他方式在 Golang Struct 中的字段中添加选择,如果我能做到的话。

我的模型是这样的

type User struct{
   FirstName string  `gorm:"size:100" json:"first_name"`
   LastName  string  `gorm:"size:100" json:"last_name"`
   Email     *string `gorm:"size:250;index;not null;index:email;unique" json:"email"`
   Role      string  `gorm:"default:User;not null" json:"is_active"` // TODO Add Choice
}

我想从 ['Admin', 'User', 'Guest'] 向我的用户模型中的角色字段添加选项。有没有办法使用 GORM 或任何其他可以解决我的问题的方法来实现它?如果没有直接的方法,我可以将其设为外键。我正在使用 PostgreSQL 来存储表。提前致谢!

【问题讨论】:

    标签: database go go-gorm


    【解决方案1】:

    对于PostGreSQL首先在你的数据库中手动创建枚举

    CREATE TYPE user_access AS ENUM (
        'admin',
        'user'
    );
    

    然后

    type Role string
    
    const (
        Admin  Role = "admin"
        User   Role = "user"
    )
    
    func (r *Role) Scan(value interface{}) error {
        *r = Role(value.([]byte))
        return nil
    }
    
    func (r Role) Value() (driver.Value, error) {
        return string(r), nil
    }
    
    type User struct{
       ID        int64   `json:"id"`
       FirstName string  `gorm:"size:100" json:"first_name"`
       LastName  string  `gorm:"size:100" json:"last_name"`
       Email     *string `gorm:"size:250;index;not null;index:email;unique" json:"email"`
       Role      Role    `sql:"type:user_access"` // PostGreSQL
       Role      Role    `json:"role" sql:"type:ENUM('admin', 'user')"` // MySQL
    }
    

    更多信息您可以查看github issuedoc

    【讨论】:

    • 您可能应该包括它是 Postgres 特定解决方案的事实。
    【解决方案2】:

    假设您在 rolesusers 之间存在一对一的关系,那么使用外键的一种方法是这样的:

    type User struct{
       ID        int64 `json:"id"`
       FirstName string  `gorm:"size:100" json:"first_name"`
       LastName  string  `gorm:"size:100" json:"last_name"`
       Email     *string `gorm:"size:250;index;not null;index:email;unique" json:"email"`
       RoleID    int64  `json:"role_id"` 
       Role      *Role `json:"role"`
    }
    
    type Role struct {
       ID   int64 `json:"id"`
       Name string `json:"name"`
    }
    
    //load data
    var users []User
    err := db.Preload("Role").Find(&users).Error
    

    编辑:多对多解决方案 关系

    假设您有一个类似users_roles 的表来链接usersroles 表,一个解决方案可能如下所示:

    type User struct{
       ID        int64 `json:"id"`
       FirstName string  `gorm:"size:100" json:"first_name"`
       LastName  string  `gorm:"size:100" json:"last_name"`
       Email     *string `gorm:"size:250;index;not null;index:email;unique" json:"email"`
       Roles      []*Role `gorm:"many2many:users_roles;" json:"roles"`
    }
    
    type Role struct {
       ID   int64 `json:"id"`
       Name string `json:"name"`
    }
    
    //load data
    var users []User
    err := db.Preload("Roles").Find(&users).Error
    

    【讨论】:

    • 如果我不想创建另一个关系,有没有办法将其定义为列表并直接使用它?
    • 如果它表示可以在该特定列中插入的受限值列表,您可能需要检查检查约束gorm.io/docs/constraints.html#CHECK-Constraint
    • 谢谢艾敏。只是好奇我是否想向角色添加多个值,假设用户可以是管理员也可以是普通普通用户。这是通过检查约束还是其他方式完成的?
    • 我已经用多对多关系的潜在解决方案更新了答案。
    猜你喜欢
    • 1970-01-01
    • 2020-02-08
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多