多值列表外键 sql gorm

Multi value list foreign key sql gorm

type Users struct {
    ID           int64      
    Email        string         
    Permissions  string
}
type UserPermissions  struct {
    ID          int64
    Description json.RawMessage
}

用户json应该是这样的:

{
    "status": 200,
    "data": {
        "id": 1,
        "email": "hello@hello.com",
        "permisions": [{
            "id":"1",
            "description":"Create permission"
         },
         {
            "id":"3",
            "description":"Edit permission"
         }]
    }
}

我的用户权限中有以下字符串:

';1;3;5;7;'每个数字都是与UserPermissions相关的id struct/table

如何使用 gorm 将字符串与用户权限 table 匹配?。 我正在使用 mysql

您问题的答案(如果您使用 PostgreSQL 作为数据库)。

如果要查询给定用户记录的权限,给定其 ID

perms := []Permission{}
err := db.Joins("JOIN users u ON id::string IN STRING_TO_ARRAY(TRIM(';' FROM u.permissions), ';')").
    Where("u.id = ?", userID).
    Find(&perms).
    Error

if err != nil {
    log.Fatal(err) // or something like that
}

如您所见,我们正在使用一些函数进行时髦的连接,这些函数将权限字段清理并拆分为单独的字符串 ID。这是笨重、脆弱、超级缓慢和复杂的,并且源于您开始时的错误关系设计。

编辑:没关系,对于 MySQL 等效的解决方案要复杂得多,所以我建议您改用下面的建议。

更好的方法

如果您可以控制数据库设计,那么更好的方法是 通过不将 ID 数组存储为字符串,这在数据库设计中从来都不是一件好事,而是在 HasMany 关系的多边上使用外键*。

go 结构看起来像这样:

type User struct {
    ID           int64             `json:"id"`     
    Email        string            `json:"email"`
    Permissions  []UserPermission  `json:"permissions"`
}

type UserPermissions struct {
    ID          int64            `json:"id"`
    UserID      int64            `json:"-"`
    Description json.RawMessage  `json:"description"`
}

// now you can use gorm to query the permissions that are related to a user
user := User{}
err := db.Preload("Permissions").First(&user, userID).Error
if err != nil {
    log.Fatal(err)
}
// now you can access user.Permissions[i].Description for example.
// or marshal to json
out, err := json.Marshal(user)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(out))

*:我假设 User 和 UserPermission 之间的关系是一对多的。这很可能不是这种情况,多对多关系实际上是有意义的(一个用户可以拥有多个权限,一个权限可以属于多个用户)。如果是这种情况,概念是相同的,您应该能够按照 many to many relationships.

上的 Gorm 指南修改此解决方案