Горм принадлежит к отношениям без возврата

# #sql #go #go-gorm

Вопрос:

У меня есть эти модели

     type Message struct {
    gorm.Model
    UserID  uint `json:"userId"`
    User    userModels.User
    Content string `json:"content"`
}

type Receiver struct {
    gorm.Model
    UserID    uint `json:"userId"`
    User      userModels.User
    FirstName string `json:"firstName"`
    LastName  string `json:"lastName"`
    Email     string `json:"email"`
    Address   string `json:"address"`
    Phone     string `json:"phone"`
}

type Delivery struct {
    gorm.Model
    Message      Message   `json:"message"`
    MessageID    uint      `json:"messageId"`
    Receiver     Receiver  `json:"Receiver"`
    ReceiverID   uint      `json:"receiverId"`
    DeliveryDate time.Time `json:"deliveryDate"`
    Sent         bool      `json:"sent"`
}
 

Я вставляю некоторую доставку в базу данных с определенными идентификаторами MessageId и ReceiverID. Когда я запрашиваю эту определенную доставку, я ожидаю получить соответствующее сообщение с идентификатором MessageId и получателем идентификатора ReceiverID.
Но то, что я получаю, — это Доставка как с пустым сообщением, так и с объектами получателя.

вот что я получаю:

  {
            "ID": 2,
            "CreatedAt": "2021-08-26T04:44:33.366628 04:30",
            "UpdatedAt": "2021-08-26T04:44:33.366628 04:30",
            "DeletedAt": null,
            "message": {
                "ID": 0,
                "CreatedAt": "0001-01-01T00:00:00Z",
                "UpdatedAt": "0001-01-01T00:00:00Z",
                "DeletedAt": null,
                "userId": 0,
                "User": {
                    "ID": 0,
                    "CreatedAt": "0001-01-01T00:00:00Z",
                    "UpdatedAt": "0001-01-01T00:00:00Z",
                    "DeletedAt": null,
                    "firstName": "",
                    "lastName": "",
                    "email": "",
                    "password": "",
                    "country": "",
                    "dateOfBirth": "0001-01-01T00:00:00Z",
                    "rank": "",
                    "gender": "",
                    "plan": ""
                },
                "content": ""
            },
            "messageId": 2,
            "Receiver": {
                "ID": 0,
                "CreatedAt": "0001-01-01T00:00:00Z",
                "UpdatedAt": "0001-01-01T00:00:00Z",
                "DeletedAt": null,
                "userId": 0,
                "User": {
                    "ID": 0,
                    "CreatedAt": "0001-01-01T00:00:00Z",
                    "UpdatedAt": "0001-01-01T00:00:00Z",
                    "DeletedAt": null,
                    "firstName": "",
                    "lastName": "",
                    "email": "",
                    "password": "",
                    "country": "",
                    "dateOfBirth": "0001-01-01T00:00:00Z",
                    "rank": "",
                    "gender": "",
                    "plan": ""
                },
                "firstName": "",
                "lastName": "",
                "email": "",
                "address": "",
                "phone": ""
            },
            "receiverId": 1,
            "deliveryDate": "2021-08-25T05:18:27.950457 04:30",
            "sent": false
        } 

В то время как я ожидаю, что он вернет сообщение с указанным мной идентификатором сообщения, а также получателем

Ответ №1:

When I query that certain Delivery

как поживаете?

если вы используете предварительную загрузку
db.Preload("Message").Preload("Receiver").First(amp;d3)

вы получите представление о получателе и сообщении, как

если вы не используете предварительную загрузку, вы получите доставку как с пустым сообщением, так и с объектами получателя.

если вам нужны только MessageId и receiverID, вам следует изменить Message Message на Message *Message и Receiver Receiver на Receiver *Receiver

если вы используете предварительную загрузку -> то же самое, что и выше

если вы не используете предварительную загрузку -> Приемник, и сообщение будет равно нулю

ниже приведен весь тестовый код и отладочная информация:

 type User3 struct {
    gorm.Model
    Name      string
}
type Message struct {
    gorm.Model
    UserID  uint `json:"userId"`
    User    *User3
    Content string `json:"content"`
}

type Receiver struct {
    gorm.Model
    UserID    uint `json:"userId"`
    User      *User3
    FirstName string `json:"firstName"`
    LastName  string `json:"lastName"`
    Email     string `json:"email"`
    Address   string `json:"address"`
    Phone     string `json:"phone"`
}

type Delivery struct {
    gorm.Model
    Message      *Message   `json:"message"`
    MessageID    uint      `json:"messageId"`
    Receiver     *Receiver  `json:"Receiver"`
    ReceiverID   uint      `json:"receiverId"`
    DeliveryDate time.Time `json:"deliveryDate"`
    Sent         bool      `json:"sent"`
}
func main() {
    db := config.CreateMysql()
    db.AutoMigrate(Delivery{})
    d := Delivery{Message: amp;Message{User: amp;User3{Name: "a"}, Content: "hello b~"}, Receiver: amp;Receiver{User: amp;User3{Name: "b"}}, DeliveryDate: time.Now(), Sent: false}
    db.Create(amp;d)
    d2 := Delivery{}
    db.First(amp;d2)
    fmt.Printf("%vn", d2)
    d3 := Delivery{}
    db.Preload("Message").Preload("Receiver").First(amp;d3)
    fmt.Printf("%vn", d3)
}
 

введите описание изображения здесь

ps: вышеуказанный пользователь равен нулю, если вы хотите предварительно загрузить вложенные ассоциации, используйте следующие:
.Preload("Message.User")
https://gorm.io/docs/preload.html

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

1. Спасибо за ваше подробное объяснение. Это решает большинство моих проблем. Другая проблема, однако, заключается в том, что я не знаю, как я могу получить доступ к вложенным дочерним элементам. например, здесь сообщения имеют свойство пользователя, которое является другой моделью. Я тоже хочу получить доступ к этому свойству из доставки.

2. в приведенном выше «ps» показано, как предварительно загрузить вложенные ассоциации db.Preload("Message").Preload("Receiver").Preload("Message.User").First(amp;d3) , Пользователь сообщения получит данные, db.Preload("Message").Preload("Receiver").Preload("Message.User").Preload("Receiver.User").First(amp;d3) как получатель. Сообщение пользователя. Пользователь получит данные,