GORM不会创建多对多关联。

huangapple go评论75阅读模式
英文:

GORM don't create many2many associations

问题

我有一个模型:

type Book struct {
	gorm.Model
	Title       string `json:"title"`
	Author      string `json:"author"`
	Description string `json:"description"`
	Category    string `json:"Category"`
	Publisher   string `json:"publisher"`
	AuthorsCard []*AuthorsCard `gorm:"many2many:book_authorscard;" json:"authorscard"`
}

type AuthorsCard struct {
	gorm.Model
	Name        string `json:"name"`
	Age         int    `json:"age"`
	YearOfBirth int    `json:"year"`
	Biography   string `json:"biography"`
}

在执行 db.AutoMigrate(&models.Book{}, &models.AuthorsCard{}) 后,我有一个创建函数:

func TestCreate() {
	var testbook = models.Book{
		Title:  "Test",
		Author: "tst",
		AuthorsCard: []*models.AuthorsCard{
			{
				Age:         23,
				Name:        "test",
				YearOfBirth: 1999,
				Biography:   "23fdgsdddTEST",
			},
		},
		Description: "something",
	}
	db.Preload("AuthorsCard").Find(&models.Book{})

	db.Create(&testbook)

}

尽管 AuthorsCard 中有一些数据,但我收到的响应是:

{
        "ID": 78,
        "CreatedAt": "2022-06-23T13:10:58.01629+03:00",
        "UpdatedAt": "2022-06-23T13:10:58.01629+03:00",
        "DeletedAt": null,
        "title": "Test",
        "author": "tst",
        "description": "something",
        "Category": "",
        "publisher": "",
        "authorscard": null
    }

如你所见,"authorscard" 是 null。

我该如何将 "authorscard" 保存到数据库中?
我使用的是 Gorm + PostgreSQL,我还用 Postman 发送了一些请求,结果都是一样的 - Authors card 是 null。

英文:

I have model:

type Book struct {
	gorm.Model
	Title       string `json:"title"`
	Author      string `json:"author"`
	Description string `json:"description"`
	Category    string `json:"Category"`
	Publisher   string `json:"publisher"`
	AuthorsCard []*AuthorsCard `gorm:"many2many:book_authorscard; "json:"authorscard"`
}

type AuthorsCard struct {
	gorm.Model
	Name        string `json:"name"`
	Age         int    `json:"age"`
	YearOfBirth int    `json:"year"`
	Biography   string `json:"biography"`
}

After db.AutoMigrate(&models.Book{}, &models.AuthorsCard{})
I have a creation function:

func TestCreate() {
	var testbook = models.Book{
		Title:  "Test",
		Author: "tst",
		AuthorsCard: []*models.AuthorsCard{
			{
				Age:         23,
				Name:        "test",
				YearOfBirth: 1999,
				Biography:   "23fdgsdddTEST",
			},
		},
		Description: "something",
	}
	db.Preload("AuthorsCard").Find(&models.Book{})

	db.Create(&testbook)

}

despite That AuthorsCard has some data in it, I receive this as a response:

{
        "ID": 78,
        "CreatedAt": "2022-06-23T13:10:58.01629+03:00",
        "UpdatedAt": "2022-06-23T13:10:58.01629+03:00",
        "DeletedAt": null,
        "title": "Test",
        "author": "tst",
        "description": "something",
        "Category": "",
        "publisher": "",
        "authorscard": null
    }

As you can see "authorscard" is null.

How can I save "authorscard" to the database?
I used Gorm + postgresql and also I sent a few request with postman, results are the same - Authors card is null

答案1

得分: 2

代码在正确的顺序下调用时是有效的:

func TestCreate() {
    db := getDB()
    db.AutoMigrate(&Book{}, AuthorsCard{})

    var testbook = Book{
        Title:  "Test",
        Author: "tst",
        AuthorsCard: []*AuthorsCard{
            {
                Age:         23,
                Name:        "test",
                YearOfBirth: 1999,
                Biography:   "23fdgsdddTEST",
            },
        },
        Description: "something",
    }

    // 1. 创建 testbook。
    db.Create(&testbook)

    // 2. 将其存储到变量中:
    var b1 *Book
    db.Preload("AuthorsCard").Find(&b1)

    fmt.Println(b1.AuthorsCard[0].Age)
    fmt.Println(b1.AuthorsCard[0].Name)
    fmt.Println(b1.AuthorsCard[0].YearOfBirth)
    fmt.Println(b1.AuthorsCard[0].Biography)
}

输出结果:

> 23
> test
1999
23fdgsdddTEST

此外,由于你传递了一个 AuthorsCard 的指针,并且在这些情况下编组不总是正常工作,所以你的 JSON 导出可能会失败。然而,GORM 在这里做得很好。

静态检查还给了我一些提示:

type Book struct {
    gorm.Model
    Title       string         `json:"title"`
    Author      string         `json:"author"`
    Description string         `json:"description"`
    Category    string         `json:"category"`
    Publisher   string         `json:"publisher"`
    AuthorsCard []*AuthorsCard `gorm:"many2many:book_authorscard" json:"authorscard"` // 错误的空格
}
英文:

The code is working when it's called in the correct order:

func TestCreate() {
	db := getDB()
	db.AutoMigrate(&Book{}, AuthorsCard{})

	var testbook = Book{
		Title:  "Test",
		Author: "tst",
		AuthorsCard: []*AuthorsCard{
			{
				Age:         23,
				Name:        "test",
				YearOfBirth: 1999,
				Biography:   "23fdgsdddTEST",
			},
		},
		Description: "something",
	}

    // 1. Create your testbook.
	db.Create(&testbook)

    // 2. Store it into a variable:
	var b1 *Book
	db.Preload("AuthorsCard").Find(&b1)
    
	fmt.Println(b1.AuthorsCard[0].Age)
	fmt.Println(b1.AuthorsCard[0].Name)
	fmt.Println(b1.AuthorsCard[0].YearOfBirth)
	fmt.Println(b1.AuthorsCard[0].Biography)

}

prints:

> 23
> test
1999
23fdgsdddTEST

Also your JSON export might fail since you pass a pointer to AuthorCard and the marshalling not always works properly in those cases. However, GORM does the right job here.

Static check also gave me some hints here:

type Book struct {
	gorm.Model
	Title       string         `json:"title"`
	Author      string         `json:"author"`
	Description string         `json:"description"`
	Category    string         `json:"Category"`
	Publisher   string         `json:"publisher"`
	AuthorsCard []*AuthorsCard `gorm:"many2many:book_authorscard" json:"authorscard"` // wrong space
}

huangapple
  • 本文由 发表于 2022年6月24日 17:02:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/72741544.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定