避免循环-递归m2m关系自引用

时间:2019-05-09 13:02:34

标签: mysql database go

这不是关于golang或mysql的问题,它是一个更普遍的问题。希望我还在正确的地方,并且有人可以帮助我解决这个问题。

我有一个结构角色,该结构可以具有多个子角色。

type Role struct{
    Name string
    Children []Role
}

因此,假设角色A有一个子角色B,角色B有一个子角色C。

在我的前端,m2m关系显示为多选HTML字段。 为了避免无限循环(A-B-C-A ...),我希望用户不能输入相关角色之一。

例如,角色C不应显示角色A和B,因为如果用户选择角色A和B,则会发生无限循环。

后端中的数据库如下所示:

角色表(主表) ID,名称,...

role_roles (连接表) role_id,child_id

我创建了此帮助程序方法来检测不应显示的ID。它正在检查角色C是否在字段 child_id 中某处,然后获取此条目的 role_id 并再次执行相同的操作。这行得通,但是看起来真的很不专业,我想知道如何用一种更优雅的方式来解决这个问题,并且用更少的SQL查询...

// whereIDLoop returns the ids which should get excluded
func whereIDLoop(id int) ([]int, error) {
    ids := []int{}
    b := builder.GlobalBuilder
    rows, err := b.Select("role_roles").Columns("role_id").Where("child_id = ?", id).All()
    if err != nil {
        return nil, err
    }

    for rows.Next() {
        var id int
        if err := rows.Scan(&id); err != nil {
            return nil,err
        }
        ids = append(ids, id)
        id2,err := whereIDLoop(id)
        if err != nil {
            return nil, err
        }
        if id2 != nil{
            ids = append(ids, id2...)
        }
    }

    err = rows.Close()
    if err != nil {
        return nil, err
    }

    return ids, nil
}

感谢您的帮助。 欢呼声

1 个答案:

答案 0 :(得分:0)

不能说最佳实践,我的建议是将验证逻辑放在应用程序层。

  1. JS中的帮助程序功能,用于过滤这样的多选选项
  2. API中的验证逻辑
  3. 存储库层的验证逻辑。
  4. 在有圆圈的情况下跟踪应用时的角色。