gorm / go как правильно объединить две таблицы?

#postgresql #go #join #go-gorm

#postgresql #Вперед #Присоединиться #go-gorm

Вопрос:

Структура моего сообщения ;

 type Message struct {
  Id          int    `json:"id" gorm:"primaryKey;AUTO_INCREMENT"`
  Message     string `json:"message"`
  Sender      int    `json:"sender" gorm:"foreignKey:users"`
  ChatId      int    `json:"chatid" gorm:"index"`
  CreatedAt   int64  `json:"createdat" gorm:"autoCreateTime"`
  MessageType int    `json:"messagetype"` // 0 representing text , 1 representing image
  Image       string `json:"image"`       // will be empty if the image doesn't contain image
}
 

Моя структура пользователя;

 type User struct {
  ID                 int    `gorm:"primaryKey;AUTO_INCREMENT"`
  Username           string `gorm:"not null"`
  Mail               string `gorm:"not null"`
  Password           string `gorm:"not null"`
  Updated            int64  `gorm:"autoUpdateTime:milli"`
  Created            int64  `gorm:"autoCreateTime"`
  RegisterMethod     string `gorm:"not null"`
  IsEmailValidated   bool   `gorm:"default:false"`
  IsOnboardCompleted bool   `gorm:"default:false"`
}
 

Вот мой запрос ;

 messages := []model.Message{}
err := r.db.Joins("inner join users on messages.sender = users.id").Where("chat_id = ?", chatid).Order("created_at desc").Limit(10).Find(amp;messages).Error
 

вот результат ;

  {
    "id": 1,
    "message": "csacsacsa",
    "sender": 16,
    "chatid": 0,
    "createdat": 0,
    "messagetype": 0,
    "image": ""
},
 

чего я хочу добиться, так это присоединиться к объекту пользователя, используя раздел «отправитель», например

 {
        "id": 1,
        "message": "csacsacsa",
        "sender": {
          "id":16,
          "username": "bla bla bla",
          "mail": "bla bla bla" 
          ....
        },
        "chatid": 0,
        "createdat": 0,
        "messagetype": 0,
        "image": ""
},
 

Ответ №1:

Вам нужно добавить поле в свою Message структуру, чтобы сохранить всю информацию для отправителя.

Изменения структуры сообщения:

 type Message struct {
  Id          int    `json:"id" gorm:"primaryKey;AUTO_INCREMENT"`
  Message     string `json:"message"`
  Sender      int    `json:"senderid" gorm:"foreignKey:users"`
  SenderObj   User   `json:"sender" gorm:"foreignKey:ID;references:Sender"`
  ChatId      int    `json:"chatid" gorm:"index"`
  CreatedAt   int64  `json:"createdat" gorm:"autoCreateTime"`
  MessageType int    `json:"messagetype"` 
  Image       string `json:"image"`       
}
 

С помощью этого вы можете использовать Preload функцию для загрузки SenderObj поля.

 messages := []model.Message{}
err := r.db.Preload("SenderObj").Where("chat_id = ?", chatid).Order("created_at desc").Limit(10).Find(amp;messages).Error
 

Комментарии:

1. Большое спасибо за ответ, как насчет выбора некоторых специальных столбцов? Теперь он возвращает весь объект пользователя с некоторыми ненужными данными, такими как пароль электронной почты, я хотел выбрать несколько разделов от пользователя, например, имя пользователя и идентификатор

2. Вы можете проверить gorm.io/docs/preload.html#Custom-Preloading-SQL . Я знаю, что на этот конкретный вопрос есть ответ SO (с использованием Preload функции с Select функцией), я просто не могу найти его прямо сейчас.