golang, создавая связь между двумя моделями и получая их с помощью Preload, используя gorm
Я изучаю golang с помощью gqlgen и gorm as orm, я создаю приложение с использованием двух моделей пользователя и сообщений, где у пользователя есть список сообщений, а у сообщений есть отправитель и получатель. Я сделал их такими
type User struct {
ID string `json:"id" gorm:"primary_key;type:uuid;default:uuid_generate_v4()"`
Username string `json:"username"`
Email string `json:"email"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Messages []*Message `json:"messages"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `json:"deleted_at" sql:"index"`
}
type Message struct {
ID string `json:"id" gorm:"primary_key;type:serial"`
Title string `json:"title"`
Body string `json:"body"`
DueDate time.Time `json:"dueDate"`
IsViewed bool `json:"isViewed" gorm:"default:false"`
SenderID string `json:"senderId" gorm:"type:uuid"`
Sender *User `json:"sender" gorm:"foreignkey:SenderID"`
RecipientID string `json:"recipientId" gorm:"type:uuid"`
Recipient *User `json:"recipient" gorm:"foreignkey:RecipientID"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `json:"deleted_at" sql:"index"`
}
когда я получаю данные сообщений с помощью Preload
var messages []*models.Message
err := db.
Preload("Sender").
Preload("Recipient").
Find(&messages).Error
if err != nil {
return nil, err
}
return messages, err
он работает отлично, но моя проблема заключается в том, что я пытаюсь получить пользователя с предварительно загруженными сообщениями.
var users []*models.User
err := db.
Preload("Messages").
Find(&users).Error
if err != nil {
return nil, err
}
return users, err
это дает мне следующую ошибку can't preload field Messages for models.User
Я знаю, что могу неправильно спроектировать свою схему, если есть лучший способ ее организовать, я был бы очень признателен, заранее спасибо.
2 ответа
Я думаю, вам следует разделять сообщения в User
к SentMessages
а также ReceivedMessages
. Затем вы можете указать внешние ключи вUser
как это:
SentMessages []*Message `gorm:"foreignkey:SenderID" json:"sentMessages"`
ReceivedMessages []*Message `gorm:"foreignkey:RecipientID" json:"receivedMessages"`
затем используйте его следующим образом:
var users []*models.User
err := db.
Preload("SentMessages").
Preload("ReceivedMessages").
Find(&users).Error
if err != nil {
return nil, err
}
return users, err
это должно работать как ты хочешь
Я думаю, вам нужно более внимательно изучить, как создается ассоциация (фактически создается из официального пакета gorm), например(&Model{}).Create(target).Association("Column").Append(&related_instance)
Поэтому, когда вы повторите попытку с помощью Preload, все будет в порядке. И, кстати, это работает с вашим текущим дизайном. Надеюсь, поможет.