Diego Gallo
Diego Gallo

Reputation: 155

Gorm Has Many relationship can't append more than one model instance during association

Summary

Main question: Can I append more than one model instance in a hasMany relationship in gorm or should I use a ManyToMany relationship? E.g. A Product model would have more than one Image model instance. Here are the relevant models:

type Publication struct {
    ID        string    `gorm:"not null"`
    CreatedAt time.Time `sql:"DEFAULT:CURRENT_TIMESTAMP" json:"created_at"`
    UpdatedAt time.Time `sql:"DEFAULT:CURRENT_TIMESTAMP" json:"updated_at"`
    Views     uint64    `gorm:"default:0" json:"views"`
    Product Product `gorm:"foreignkey:ID" json:"product"`
}
type Product struct {
    ID           string `gorm:"not null"`
    Title        string
    Price        uint64
    Images       []ProductImage `gorm:"foreignkey:ID" json:"images"`
}
type ProductImage struct {
    ID   string
    Name string
}

During Server Initialization, I create, associate and load some data to the MySQL DB in the following way:

err = db.Debug().Model(&models.Product{}).Create(&mk_list_products[i]).Error
        if err != nil {
            log.Fatal(err)
        }
        err = db.Debug().Model(&models.Publication{}).Create(&mk_list_publications[i]).Error
        if err != nil {
            log.Fatal(err)
        }
        err = db.Debug().Model(&mk_list_products[i]).Association("Images").Append(&product_images)
        if err != nil {
            log.Fatal(err)
        }

I'm querying Publication model with Product Association as follow:

pbs := []models.Publication{}
    err = db.
        Debug().
        Preload("Product.Images").
        Model(&models.Publication{}).
        Limit(3).
        Where("created_at <= ?", time.Now()).
        Find(&pbs).Error
    if err != nil {
        console.Pretty(err)
        return
    }

For Publication with ID=3 (similar with the rest) I get

{
"ID": "3",
"created_at": "2022-01-06T21:26:41.585-06:00",
"updated_at": "2022-01-07T21:26:42.154-06:00",
"views": 0,
"product": {
"ID": "3",
"Title": "Product Title A",
"Price": 200,
"category": {
"ID": "",
"Parent": "",
"Image": "",
"Order": 0,
"Name": "",
"Description": "",
"Slug": ""
},
"State": "",
"Description": "Some Description",
"Availability": "",
"Brand": "Some Brand",
"labels": null,
"SKU": "Some SKU",
"images": [
{
"ID": "3",
"Name": "/path/cannabis_product_1.png"
}
]
}

Expected result

    {
    "ID": "3",
    "created_at": "2022-01-06T21:26:41.585-06:00",
    "updated_at": "2022-01-07T21:26:42.154-06:00",
    "views": 0,
    "product": {
    "ID": "3",
    "Title": "Product Title A",
    "Price": 200,
    "category": {
    "ID": "",
    "Parent": "",
    "Image": "",
    "Order": 0,
    "Name": "",
    "Description": "",
    "Slug": ""
    },
    "State": "",
    "Description": "Some Description",
    "Availability": "",
    "Brand": "Some Brand",
    "labels": null,
    "SKU": "Some SKU",
    "images": [
{
    "ID": "2",
    "Name": "/path/cannabis_product_2.png"
    }    
{
    "ID": "3",
    "Name": "Name": "/path/cannabis_product_3.png""
    }
    ]
    }

Upvotes: 1

Views: 704

Answers (1)

Diego Gallo
Diego Gallo

Reputation: 155

Solution

I still don't understand why declaring the ID of ImageProduct as the foreign on the Product model gives unexpected result. To make this work, I had to defined and add a different foreignKey other than ID on product Imagesfield

type Product struct {
    ID           string `gorm:"not null"`
    Title        string
    Price        uint64
    ...
    Images       []ProductImage `gorm:"foreignkey:ProductId" json:"images"`
}

Then, on the ProductImage model I added an additional field ProductId

type ProductImage struct {
    ID        string
    ProductId string
    Name      string
}

After appending two test ProductImage instances to Publication with ID=3 I get the expected result.

err = db.Debug().Model(&mk_list_products[2]).Association("Images").Append(&product_images[2], &product_images[3])
    if err != nil {
        log.Fatal(err)
    }
...
{
"ID": "3",
"created_at": "2022-01-07T11:20:32.298-06:00",
"updated_at": "2022-01-08T11:20:32.867-06:00",
"views": 0,
"product": {
"ID": "3",
"Title": "Product Title 3",
"Price": 200,
"category": {
"ID": "",
"Parent": "",
"Image": "",
"Order": 0,
"Name": "",
"Description": "",
"Slug": ""
},
"State": "",
"Description": "Some Description",
"Availability": "",
"Brand": "Some Brand",
"labels": null,
"SKU": "Some SKU",
"images": [
{
"ID": "3",
"ProductId": "3",
"Name": "/path/cannabis_product_3.png"
},
{
"ID": "4",
"ProductId": "3",
"Name": "/path/cannabis_product_4.png"
}
]
}
}

Upvotes: 1

Related Questions