many2many
go
type AdminRoleModel struct {
database.BaseModel
Name string `gorm:"size:255;not null"`
Description string `gorm:"type:text"`
Permissions []AdminPermissionModel `gorm:"many2many:admin_role_permissions;joinForeignKey:RoleID;joinReferences:PermissionID"`
}
func (AdminRoleModel) TableName() string {
return "admin_roles"
}go
// 这里的数据根据 permission 自动与数据库对其
type AdminPermissionModel struct {
database.BaseModel
Key string `gorm:"size:255;not null;uniqueIndex"`
Name string `gorm:"size:255;not null"`
Desc string `gorm:"type:text"`
// 是否为代码中仍然存在的权限
Enabled bool `gorm:"not null;default:true"`
// 可选:用于标记是否系统内置,不允许后台随意删除
Builtin bool `gorm:"not null;default:true"`
}
func (AdminPermissionModel) TableName() string {
return "admin_permissions"
}go
// 关系定义
type AdminRolePermissionModel struct {
RoleID int64 `gorm:"not null;uniqueIndex:idx_role_permission"`
PermissionID int64 `gorm:"not null;uniqueIndex:idx_role_permission"`
}
func (AdminRolePermissionModel) TableName() string {
return "admin_role_permissions"
}create
go
func CreateRole(db *gorm.DB, name string, desc string, permissionKeys []string) error {
return db.Transaction(func(tx *gorm.DB) error {
var permissions []AdminPermissionModel
if len(permissionKeys) > 0 {
if err := tx.
Where("key IN ?", permissionKeys).
Where("enabled = ?", true).
Find(&permissions).Error; err != nil {
return err
}
}
role := AdminRoleModel{
Name: name,
Description: desc,
Permissions: permissions,
}
return tx.Create(&role).Error
})
}select
注意 Preload
go
func GetRoleByID(db *gorm.DB, roleID int64) (*AdminRoleModel, error) {
var role AdminRoleModel
err := db.
Preload("Permissions", "enabled = ?", true).
First(&role, roleID).
Error
if err != nil {
return nil, err
}
return &role, nil
}go
func ListRoles(db *gorm.DB) ([]AdminRoleModel, error) {
var roles []AdminRoleModel
err := db.
Preload("Permissions", "enabled = ?", true).
Order("id DESC").
Find(&roles).
Error
return roles, err
}sql 拼接
go
func GetRolePermissionKeys(db *gorm.DB, roleID int64) ([]string, error) {
var keys []string
err := db.
Table("admin_permissions").
Select("admin_permissions.key").
Joins(`
JOIN admin_role_permissions
ON admin_role_permissions.permission_id = admin_permissions.id
`).
Where("admin_role_permissions.role_id = ?", roleID).
Where("admin_permissions.enabled = ?", true).
Pluck("admin_permissions.key", &keys).
Error
return keys, err
}Pluck 把某一列直接提取到 slice 里
update
Association
Association 专门用来操作“关系”的 API(不是操作表数据本身)
Association 指定 “操作哪个关系字段”
go
func UpdateRoleInfo(db *gorm.DB, roleID int64, name string, desc string) error {
return db.Model(&AdminRoleModel{}).
Where("id = ?", roleID).
Updates(map[string]any{
"name": name,
"description": desc,
}).Error
}替换权限
go
func ReplaceRolePermissions(db *gorm.DB, roleID int64, permissionKeys []string) error {
return db.Transaction(func(tx *gorm.DB) error {
var role AdminRoleModel
if err := tx.First(&role, roleID).Error; err != nil {
return err
}
var permissions []AdminPermissionModel
if len(permissionKeys) > 0 {
if err := tx.
Where("key IN ?", permissionKeys).
Where("enabled = ?", true).
Find(&permissions).
Error; err != nil {
return err
}
}
return tx.Model(&role).
Association("Permissions").
Replace(permissions)
})
}追加权限
go
db.Model(&role).Association("Permissions").Append(perms)移除权限
go
db.Model(&role).Association("Permissions").Delete(perms)清空权限
go
db.Model(&role).Association("Permissions").Clear()Find(查询关系)
go
var perms []AdminPermissionModel
db.Model(&role).Association("Permissions").Find(&perms)delete
go
func DeleteRole(db *gorm.DB, roleID int64) error {
return db.Transaction(func(tx *gorm.DB) error {
var role AdminRoleModel
if err := tx.First(&role, roleID).Error; err != nil {
return err
}
if err := tx.Model(&role).
Association("Permissions").
Clear(); err != nil {
return err
}
return tx.Delete(&role).Error
})
}