简体   繁体   中英

golang, creating relation between 2 model and retrieve them with Preload using gorm

I am learning golang with gqlgen and gorm as orm, I am creating an app using with 2 models user and messages where the user has a list of messages, and the messages have sender and recipient. I have made them like the following

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"`
}

when I retrieve the messages data using Preload

var messages []*models.Message
err := db.
    Preload("Sender").
    Preload("Recipient").
    Find(&messages).Error
if err != nil {
    return nil, err
}
return messages, err

it works perfectly but my problem is when trying to retrieve the user with the messages preloaded.

var users []*models.User
err := db.
    Preload("Messages").
    Find(&users).Error
if err != nil {
    return nil, err
}
return users, err

this one gives me the following error can't preload field Messages for models.User

I know I might design my schema wrong if there's a better way to organize it I would appreciate it so much, thanks in advance.

I think you should separate messages in User to SentMessages and ReceivedMessages . Then you can specify foreign keys in User like that:

SentMessages      []*Message `gorm:"foreignkey:SenderID" json:"sentMessages"`
ReceivedMessages  []*Message `gorm:"foreignkey:RecipientID" json:"receivedMessages"`

then use it as the following:

var users []*models.User
err := db.
Preload("SentMessages").
Preload("ReceivedMessages").
Find(&users).Error
if err != nil {
  return nil, err
}
return users, err

that should work as you want

I think you've to take a closer look on how the association are made(actually create from the official gorm package) like (&Model{}).Create(target).Association("Column").Append(&related_instance)

So when you'll retry it using Preload everything gone be Ok. And BTW it work with your current design. Hope it helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM