Получить вложенный объект в структуре в gorm
У меня есть две структуры:
type GoogleAccount struct {
Id uint64
Token string
}
Он представляет мой собственный тип объекта PostgreSQL (я создал сам):
CREATE TYPE GOOGLE_ACCOUNT AS
(
id NUMERIC,
token TEXT
);
И следующая структура таблицы в БД:
type Client struct {
IdClient uint64 `gorm:"primary_key"`
Name string
PhotoUrl string
ApprovalNumber uint16
Phone string
Password string
HoursOfNotice int8
Google GoogleAccount
}
И мой пользовательский объект вложен в типе клиента и назван как google
, Я попытался прочитать данные следующим образом:
var users model.Client
db.First(&users)
Но, к сожалению, я не могу прочитать поле google
(иметь значение по умолчанию). Я не хочу создавать отдельную таблицу с google_account, или делать эту структуру как отдельные поля в клиентской таблице или упаковывать ее как json (создал отдельную сущность, потому что эта структура используется не только в этой таблице, и я ищу новые способы, которые получить тот же результат, но более изящно). Задача не состоит в том, чтобы упростить представление данных в таблице. Мне нужно сделать правильное отображение объекта от postgres до сущности.
Прямо сейчас я нашел одно решение - внедрить Scanner в GoogleAccount. Но значение в методе ввода равно []uint8. Как я могу предположить, []uint8 может приводить к строке, и после этого я могу проанализировать эту строку. Эта строка (которая хранится в БД) выглядит (x,x)
где х - это значение. Это правильный способ, чтобы разобрать строку и установить значение для объекта? Или есть способ получить этот результат с помощью ORM?
Возможен ли способ чтения этих данных как объекта вложенной структуры?
2 ответа
Прямо сейчас я нашел одно решение - внедрить Scanner для GoogleAccount
, На входе Scan
метод, который я получил []uint8
, что я приведу к строке и разобрать в конце. Эта строка (которая хранится в БД) выглядит (x,x)
- где x
- это ценность. Конечно, это не правильный способ достижения моей цели. Но я не мог найти другое решение.
Я настоятельно рекомендую использовать классическое связывание по отношениям или просто хранить эти поля в таблице как простейшее значение (а не как объект).
Но если вы хотите поэкспериментировать с вложенным объектом в таблице, вы можете взглянуть на мою реализацию, может быть, она будет вам полезна: https://github.com/kirikzyusko1996/go-cleaning-api/blob/master/src/app/model/client.go
Похоже, вы захотите сделать две вещи с тем, что у вас есть: (1) обновить модель, чтобы у вас была правильная привязка отношений, и (2) использовать .Preload()
метод, если вы пытаетесь заставить его связать данные при чтении.
Модельные Изменения
Gorm автоматически определяет отношения на основе имени атрибутов в вашей структуре и имени ссылочной структуры. Проблема в том, что Google
атрибут типа GoogleAccount
не ассоциирует, потому что Горм ищет type Google struct
,
Вам также не хватает внешнего ключа на GoogleAccount
, Как ORM узнает, какие GoogleAccount
ассоциировать с которым Client
? Вы должны добавить ClientId
на ваш GoogleAccount
определение структуры.
Кроме того, я бы изменил первичные ключи, которые вы используете для ввода uint
так как это то, что Gorm по умолчанию (если у вас нет веских причин не использовать его)
Если бы я был тобой, я бы изменил мои определения структуры следующим образом:
type Client struct {
IdClient uint `gorm:"primary_key"`
Name string
PhotoUrl string
ApprovalNumber uint16
Phone string
Password string
HoursOfNotice int8
GoogleAccount GoogleAccount // Change this to `GoogleAccount`, the same name of your struct
}
type GoogleAccount struct {
Id uint
ClientId uint // Foreign key
Token string
}
Для получения дополнительной информации об этом, посмотрите на документацию ассоциаций здесь: http://gorm.io/associations.html
Предварительная загрузка ассоциаций
Теперь, когда вы правильно их связали, вы можете .Preload()
получить вложенный объект, который вы хотите:
db.Preload("GoogleAccount").First(&user)
С помощью .Preload()
будет заселять user.GoogleAccount
атрибут с правильно связанным GoogleAccount
на основе ClientId
,
Для получения дополнительной информации об этом обратитесь к документации по предварительной загрузке: http://gorm.io/crud.html