danial dehvan
danial dehvan

Reputation: 237

Gorm belongs to does not return relations

I have these models

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

I insert some Delivery in the database with certain MessageID and ReceiverID. When I query that certain Delivery I expect to get the regarding message with the id of MessageID, and a Receiver of id ReceiverID. But what I get is a Delivery with both empty Message and Receiver objects.

this is what I get:

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

While I expect it to return the message with the messageId I specified and also the receiver

Upvotes: 2

Views: 996

Answers (1)

Para
Para

Reputation: 1387

When I query that certain Delivery

how do you do?

if you uses Preload db.Preload("Message").Preload("Receiver").First(&d3)

you will get the deltial of Receiver and message like

if you don't uses Preload what you get is a Delivery with both empty Message and Receiver objects.

if you only need messageId and receiverID you should change the Message Message to Message *Message and Receiver Receiver to Receiver *Receiver

if you uses Preload -> same to above

if you don't uses Preload -> Receiver and Message will be nil

follow is all test code and debug info:

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: &Message{User: &User3{Name: "a"}, Content: "hello b~"}, Receiver: &Receiver{User: &User3{Name: "b"}}, DeliveryDate: time.Now(), Sent: false}
    db.Create(&d)
    d2 := Delivery{}
    db.First(&d2)
    fmt.Printf("%v\n", d2)
    d3 := Delivery{}
    db.Preload("Message").Preload("Receiver").First(&d3)
    fmt.Printf("%v\n", d3)
}

enter image description here

ps: above user is nil, if you want preload nested associations, uses follow: .Preload("Message.User") https://gorm.io/docs/preload.html

Upvotes: 2

Related Questions