это меньше вопрос о golang или mysql, это более общий вопрос. Надеюсь, я все еще нахожусь в правильном месте, и кто-нибудь может помочь мне обернуть голову вокруг этого.
У меня есть структура Роль , которая может иметь несколько дочерних ролей.
type Role struct{
Name string
Children []Role
}
Допустим, у роли A есть дочерняя роль B, а у роли B детская роль C.
В моем интерфейсе отношение m2m отображается в виде HTML-поля с несколькими вариантами выбора.
Чтобы избежать бесконечного цикла (A-B-C-A ...), я хочу, чтобы пользователь не мог ввести одну из связанных ролей.
Например, роль C не должна отображать роли A и B, потому что если пользователь выберет их, произойдет бесконечный цикл.
База данных в бэкэнде выглядит так:
таблица ролей (основная таблица)
идентификатор, имя, ...
role_roles (таблица соединений)
role_id, child_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
}
Спасибо за любую помощь.
Cheers Pat