How to create foreign keys in gorm?

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

How to create foreign keys in gorm?

问题

所以我在应用程序中有两个表:usersposts。我想实现一个点赞功能,用户可以点赞一篇文章。为此,我创建了以下表格:

type Like struct {
	PostId    string    `json:"post_id"`
	UserId    string    `json:"user_id"`
	CreatedAt time.Time `json:"created_at"`
}

我的问题是,当我使用AutoMigrate方法迁移Like模型时,如何自动设置外键?

我尝试过在相应的位置使用gorm:"foreignKey:Post"gorm:"foreignKey:User"结构标签,但它们没有起作用。

我该如何使其工作?谢谢!

英文:

So I have two tables in application: users and posts. I'd like to implement a liking functionality where a user can like a post. To do this I created the following table:

type Like struct {
	PostId    string    `json:"post_id"`
	UserId    string    `json:"user_id"`
	CreatedAt time.Time `json:"created_at"`
}

My questions is how can I make it so when I AutoMigrate the Like model, foreign keys are setup automatically?

I have tried using the gorm:"foreignKey:Post" and gorm:"foreignKey:User" struct tags in their respective spots but they don't do anything.

How could I get this to work? Thank you!

答案1

得分: 1

由于您在命名中没有遵循惯例(即使用Id而不是ID,PostId而不是PostID),您需要明确告诉gorm哪个是外键,指向哪个属性。

以下是代码片段。Github链接

参考资料:

  1. Belongs To
  2. Has Many
package storage2

import (
	"log"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

type Post struct {
	Body   string `gorm:"type:text"`
	Id     string `gorm:"type:uuid;primary_key"`
	Likes  []Like `gorm:"foreignkey:PostId;references:Id"`
	User   User   `gorm:"foreignkey:UserId;references:Id"`
	UserId string
}

type Like struct {
	Id     string `gorm:"type:uuid;primary_key"`
	PostId string `gorm:"type:uuid;not null"`
	User   User   `gorm:"foreignkey:UserId;references:Id"`
	UserId string
}

type User struct {
	Id   string `gorm:"type:uuid;primary_key"`
	Name string
}

func GormTest() {
	db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info),
	})
	if err != nil {
		log.Fatal("无法打开数据库")
	}
	err = db.AutoMigrate(&User{}, &Post{}, &Like{})
	if err != nil {
		log.Fatal("无法迁移数据库")
	}
	createTestData(db)
	fetchData(db)
}

func createTestData(db *gorm.DB) {
	users := []User{
		{Id: "0b83313d-1f85-4093-8621-efd2f21419d3", Name: "Shahriar"},
		{Id: "bddd6566-bcd2-4ad1-8eb9-65a23f5a9856", Name: "John"},
		{Id: "663c1328-dce2-4527-aecb-7fc478c229c2", Name: "Durand"}}
	err := db.Create(&users).Error
	if err != nil {
		log.Println("无法创建用户数据")
	}
	like := Like{
		Id:     "45ba45fc-0900-4fcc-80dd-c394170b777b",
		UserId: users[0].Id,
	}
	post := Post{
		Id:     "4cebb4c7-d44e-4160-a2df-a06f43211d45",
		Body:   "测试帖子",
		Likes:  []Like{like},
		UserId: users[1].Id,
	}
	err = db.Create(&post).Error
	if err != nil {
		log.Println("无法创建帖子")
	}
}

func fetchData(db *gorm.DB) {
	post := Post{
		Id: "4cebb4c7-d44e-4160-a2df-a06f43211d45",
	}
	if err := db.Preload("Likes").First(&post).Error; err != nil {
		log.Println("无法加载帖子")
	}
	log.Println(post)
}

希望对您有所帮助!

英文:

As you are not following conventions (i.e. Id instead of ID, PostId instead of PostID) in naming you need to explicitly tell gorm which is the foreign key and referred to which property.

Here is the snippet. Github Link

Reference:

  1. Belongs To
  2. Has Many
package storage2
import (
"log"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
type Post struct {
Body   string `gorm:"type:text"`
Id     string `gorm:"type:uuid;primary_key"`
Likes  []Like `gorm:"foreignkey:PostId;references:Id"`
User   User   `gorm:"foreignkey:UserId;references:Id"`
UserId string
}
type Like struct {
Id     string `gorm:"type:uuid;primary_key"`
PostId string `gorm:"type:uuid;not null"`
User   User   `gorm:"foreignkey:UserId;references:Id"`
UserId string
}
type User struct {
Id   string `gorm:"type:uuid;primary_key"`
Name string
}
func GormTest() {
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
if err != nil {
log.Fatal("could not open database")
}
err = db.AutoMigrate(&User{}, &Post{}, &Like{})
if err != nil {
log.Fatal("could not migrate database")
}
createTestData(db)
fetchData(db)
}
func createTestData(db *gorm.DB) {
users := []User{
{Id: "0b83313d-1f85-4093-8621-efd2f21419d3", Name: "Shahriar"},
{Id: "bddd6566-bcd2-4ad1-8eb9-65a23f5a9856", Name: "John"},
{Id: "663c1328-dce2-4527-aecb-7fc478c229c2", Name: "Durand"}}
err := db.Create(&users).Error
if err != nil {
log.Println("failed to create user data")
}
like := Like{
Id:     "45ba45fc-0900-4fcc-80dd-c394170b777b",
UserId: users[0].Id,
}
post := Post{
Id:     "4cebb4c7-d44e-4160-a2df-a06f43211d45",
Body:   "Test Post",
Likes:  []Like{like},
UserId: users[1].Id,
}
err = db.Create(&post).Error
if err != nil {
log.Println("failed to crete post")
}
}
func fetchData(db *gorm.DB) {
post := Post{
Id: "4cebb4c7-d44e-4160-a2df-a06f43211d45",
}
if err := db.Preload("Likes").First(&post).Error; err != nil {
log.Println("failed to load post")
}
log.Println(post)
}

huangapple
  • 本文由 发表于 2022年12月28日 10:38:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/74935777.html
匿名

发表评论

匿名网友

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

确定