英文:
Gorm Has Many relationship can't append more than one model instance during association
问题
摘要
主要问题:在gorm中,我可以在hasMany
关系中追加多个模型实例吗?还是应该使用ManyToMany
关系?例如,Product
模型将具有多个Image
模型实例。
以下是相关的模型:
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
}
在服务器初始化期间,我以以下方式创建、关联和加载一些数据到MySQL
数据库:
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)
}
我使用以下方式查询具有Product Association
的Publication
模型:
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
}
对于ID=3
的Publication
(与其他相似),我得到:
{
"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"
}
]
}
}
期望的结果
{
"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": "/path/cannabis_product_3.png"
}
]
}
}
英文:
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""
}
]
}
答案1
得分: 1
解决方案
我仍然不明白为什么在 Product
模型上将 ImageProduct
的 ID
声明为外键会产生意外的结果。
为了使其工作,我不得不在产品的 Images
字段上定义并添加一个与 ID
不同的 foreignKey
type Product struct {
ID string `gorm:"not null"`
Title string
Price uint64
...
Images []ProductImage `gorm:"foreignkey:ProductId" json:"images"`
}
然后,在 ProductImage
模型上添加了一个额外的字段 ProductId
type ProductImage struct {
ID string
ProductId string
Name string
}
在将两个测试的 ProductImage
实例追加到 Publication
的 ID=3
后,我得到了预期的结果。
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"
}
]
}
}
英文:
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 Images
field
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"
}
]
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论