#go #foreign-keys #go-gorm
# #Вперед #внешние ключи #go-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
Как я могу сопоставить строку с таблицей разрешений пользователя с помощью gorm ?. Я использую mysql
Комментарии:
1. Из вашего кода неясно, есть ли один или много
UserTypes
для каждогоUser
, потому что у вас есть поле UserType в вашей структуре Users. Какова цель этого поля?2. решаемая @EzequielMuns. Я уже обновил код. Извините за недопонимание
Ответ №1:
Ответ на ваш вопрос (если вы используете PostgreSQL в качестве своей базы данных).
Если вы хотите запросить разрешения, которые имеет данная пользовательская запись, учитывая ее идентификатор
perms := []Permission{}
err := db.Joins("JOIN users u ON id::string IN STRING_TO_ARRAY(TRIM(';' FROM u.permissions), ';')").
Where("u.id = ?", userID).
Find(amp;perms).
Error
if err != nil {
log.Fatal(err) // or something like that
}
Как вы можете видеть, мы выполняем простое объединение с функциями, которые очищают и разделяют поле разрешений на отдельные идентификаторы строк. Это неуклюже, хрупко, очень медленно и запутанно, и связано с ошибочным дизайном отношений, с которого вы начали.
РЕДАКТИРОВАТЬ: Неважно, для MySQL эквивалентное решение намного сложнее, поэтому я предлагаю вам вместо этого воспользоваться приведенным ниже советом.
Лучший способ
Если у вас есть контроль над дизайном базы данных, лучшим способом сделать это было бы не хранить массив идентификаторов в виде строки, что никогда не бывает хорошо при проектировании базы данных, а вместо этого использовать внешний ключ на стороне многих отношений 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(amp;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))
*: Я предполагаю, что связь между пользователем и разрешением пользователя — один ко многим. Это вполне может быть не так, и отношение «Многие ко многим» на самом деле имеет смысл (у одного пользователя может быть много разрешений, одно разрешение может принадлежать многим пользователям). Если это так, концепции те же, и вы должны иметь возможность изменить это решение, следуя руководству Gorm по отношениям «многие ко многим«.
Комментарии:
1. Привет, @juancer1123, я отредактировал свой ответ, чтобы учесть ваше редактирование.
2. спасибо @EzequielMuns, в этом случае, как вы сказали, я создаю новую таблицу с идентификатором разрешений и идентификатором пользователя, и у меня все еще есть описания разрешений, потому что они общие, тогда мне не нужно писать описание для каждого разрешения. спасибо за совет!