Избегайте петель в - рекурсивные m2m отношения с собственной ссылкой - PullRequest
0 голосов
/ 09 мая 2019

это меньше вопрос о 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

1 Ответ

0 голосов
/ 10 мая 2019

Не могу сказать, что это лучший метод, я предлагаю разместить логику проверки на прикладном уровне.

  1. вспомогательная функция в JS для фильтрации опции в множественном выборе, как это
  2. логика проверки в API
  3. логика проверки на уровне хранилища.
  4. отслеживание ролей при применении в случае наличия круга.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...