英文:
How to Add Choices to database field using GORM
问题
我对Golang非常陌生,因为我主要使用Python进行编码,所以遇到了一个我无法解决的问题。我想通过GORM或其他任何方法向Golang结构的字段添加选择项。
我的模型如下所示:
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
}
我想在User模型的Role字段中添加选择项['Admin', 'User', 'Guest']。是否有一种方法可以使用GORM或其他方法来实现这一目标?如果没有直接的方法,我可以将其作为外键处理。我正在使用PostgreSQL来存储表。提前感谢!
英文:
I'm very new to Golang as I mostly code in Python, so came across one problem that I'm not able to solve. I want to add choices to a field in Golang Struct via GORM or any other way if I can achieve that.
My model looks like this
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
}
I want to add choices to my Role Field in User Models from ['Admin', 'User', 'Guest']. Is there a way to achieve it using GORM or any other method that will solve my problem? I can make it a Foreign key if there is no direct way to do it. I'm using PostgreSQL to store tables. Thanks in Advance!
答案1
得分: 2
假设roles
和users
之间存在一对一的关系,使用外键的一种方法如下所示:
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"`
}
// 加载数据
var users []User
err := db.Preload("Role").Find(&users).Error
编辑:处理多对多关系的解决方案
假设你有一个名为users_roles
的表,用于连接users
和roles
表,解决方案可能如下所示:
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"`
}
// 加载数据
var users []User
err := db.Preload("Roles").Find(&users).Error
英文:
Assuming you have a one-to-one relation between roles
and users
, one approach with the foreign keys would be something like this:
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
EDIT: solution for many-to-many
relationship
Assuming that you would have a table like users_roles
that links the users
and roles
tables, one solution might look like this:
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
答案2
得分: 2
首先,在你的数据库中手动创建一个枚举类型(enum):
CREATE TYPE user_access AS ENUM (
'admin',
'user'
);
然后,在Go代码中定义一个Role
类型,并实现Scan
和Value
方法:
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
}
最后,在User
结构体中使用Role
类型来表示用户的角色:
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问题和文档。
英文:
For PostGreSQL First create enum manually in your database
CREATE TYPE user_access AS ENUM (
'admin',
'user'
);
Then
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
}
For more info you can check github issue and doc
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论