Reputation: 988
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!
Upvotes: 4
Views: 2265
Reputation: 615
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:
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)
}
Upvotes: 4