响应中不存在计算的选定字段

computed selected field not present in response

我在 gorm 中有这个模型,其中有 2 个字段我不希望在 table 中,因为它们是根据 sql 查询计算的:

type User struct {
    ID          uint        `json:"id" gorm:"primarykey,autoIncrement"`
    MutedUsers     []*User `json:"-" gorm:"many2many:user_muted_users;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
    BlockedUsers   []*User `json:"-" gorm:"many2many:user_blocked_users;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"`
    ...

    IsMuted     bool `json:"is_muted" gorm:"-"`
    IsBlocked   bool `json:"is_blocked" gorm:"-"`
}

计算以上字段的查询:

var users []models.User

userMutedQ := database.Instance.
    Table("user_muted_users").
    Select("1").
    Where("user_id = ? and muted_user_id = u.id", 1)

userBlockedQ := database.Instance.
    Table("user_blocked_users").
    Select("1").
    Where("user_id = ? and blocked_user_id = u.id", 1)

database.Instance.
    Table("users u").
    Select("u.*, "+
        "(case when exists(?) then 'true' else 'false' end) as is_muted, "+
        "(case when exists(?) then 'true' else 'false' end) as is_blocked, ",
        userMutedQ, userBlockedQ, 
    ).
    Where("u.id = 1").
    Scan(&users)

来自控制台的 sql,当 运行 针对数据库时,将为 is_muted is_blocked 生成具有正确值的列(一些 true 一些false).

但是,

users 列表中 is_muted is_blocked 的所有值都为 false。由于 - 标志定义,可能 gorm 忽略了它们。如果我不使用 -,那么 gorm 将在我的数据库中创建 is_muted is_blocked 列,这些列完全是多余的,因为值总是被计算出来的。

这里的正确方法是什么?

根据文档Declaring Models/Field-Level Permission) and new feature (Add field tag to ignore migration and PR), you can use migration directive for - tag to ignore field creation during migration并使用->只读字段权限:

IsBlocked bool `gorm:"->;-:migration"`