rbac权限系统需建users、roles、permissions、role_permissions四张表,users与roles多对多关联,permissions含code/name/method/path字段,users须有deletedat软删除字段,role_permissions需联合唯一索引,gorm模型须显式声明外键、id用uint64、时间字段加autocreatetime标签、软删除字段名严格为deletedat且类型为*time.time。

GoLand 本身不参与数据库设计,它只是个 IDE;权限系统该用什么表结构、怎么写 GORM 模型、哪些字段容易漏掉约束——这些得靠你手动定,IDE 不会替你决策。
权限系统核心表该怎么建(MySQL + GORM 场景)
RBAC 是最常用也最容易落地的起点,别一上来就搞 ABAC 或策略引擎。四张表够用:users、roles、permissions、role_permissions(中间表)。users 和 roles 是多对多,靠 user_roles 关联;权限粒度控制到接口级,permissions 表里至少要有 code(如 "user:read")、name、method("GET")、path("/api/v1/users")。
-
users表必须加deleted_at字段,GORM 才能开软删除;别用is_deleted布尔值,否则关联查询时容易漏数据 -
role_permissions的联合唯一索引要显式定义:UNIQUE INDEX idx_role_perm (role_id, permission_id),不然重复赋权会静默失败 - GORM 模型里用
gorm:"foreignKey:RoleID"显式声明外键,别依赖默认命名,GoLand 的代码跳转才不会断
在 GoLand 里快速生成 GORM 模型文件
别手敲结构体。右键数据库连接 → Generate GORM Structs,选中四张表,勾上 Use snake_case 和 Generate JSON tags。生成后立刻检查三处:
- 所有 ID 字段确认是
uint或uint64,不是int;MySQL 的BIGINT UNSIGNED对应 Go 的uint64 -
CreatedAt、UpdatedAt字段必须带gorm:"autoCreateTime;autoUpdateTime"标签,否则时间不自动更新 - 软删除字段名必须严格是
DeletedAt(首字母大写),且类型为*time.Time,GORM 才认
如果生成的结构体里有 type User struct { ID int `gorm:"primarykey"` },马上改成 uint64 并补上 gorm:"primaryKey;autoIncrement" —— 否则插入时 ID 可能为 0。
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
权限校验逻辑写在哪、怎么测(避免写进 controller)
校验逻辑必须抽成独立 service 方法,比如 authz.CanAccess(ctx, userID, "user:write", "/api/v1/users/123", "PUT")。GoLand 能帮你快速重构:选中校验代码 → Refactor → Extract Method,起名 checkPermission,放 authz/ 包下。
- 别在 handler 里直接查
role_permissions表——先查缓存(Redis),key 用"perm:<user_id>"</user_id>存用户所有permission_code列表;缓存没命中再查 DB 并回填 - 测试时用
testify/mock模拟authz.Checker接口,别连真实 DB;GoLand 的 Run with Coverage 能立刻看出哪条分支没覆盖到 - 注意 HTTP method 大小写:
"PUT"≠"put",GORM 查询时用strings.ToUpper()统一处理,别依赖前端传参规范
GoLand 调试权限问题的三个关键点
遇到 “明明给了权限却 403” 时,别急着改 SQL。先在 GoLand 里做这三件事:
- 在
authz.CanAccess方法入口打条件断点:userID == 123 && permCode == "user:delete",看参数是否如预期 - 打开 Database Console,执行
SELECT * FROM role_permissions rp JOIN user_roles ur ON rp.role_id = ur.role_id WHERE ur.user_id = 123;,确认关联数据存在 - 检查 GORM 日志是否开启:
gorm.Config{Logger: logger.Default.LogMode(logger.Info)},日志里如果出现SELECT ... WHERE deleted_at > '0001-01-01'就说明软删除生效了,但你的数据可能被误标为已删
最常被忽略的是:GORM 默认开启事务,而权限校验通常走只读查询;如果校验方法被套在另一个事务里,且该事务尚未提交,user_roles 表的新记录在当前事务里不可见——此时得加 db.Session(&gorm.Session{NewDB: true}) 强制新建会话。










