Your Question
Two structs Thread & Interest have a many to many relationship with each other. According to the documentation this is how both structs looks like:
type Thread struct {
ID uuid.UUID `gorm:"primaryKey" json:"threadId"`
Title string `gorm:"not null" json:"title"`
Body string `gorm:"not null" json:"body"`
CreatedAt time.Time
UpdatedAt time.Time
// Foreign keys
UserID uuid.UUID `json:"userId"`
// Has many association
Comments []Comment `json:"comments"`
// many to many associations
Interests []Interest `gorm:"many2many:thread_interests;" json:"interests"`
UsersLiked []User `gorm:"many2many:post_likes;" json:"usersLiked"`
UsersDisliked []User `gorm:"many2many:post_dislikes;" json:"usersDisliked"`
}
type Interest struct {
ID uuid.UUID `gorm:"primaryKey" json:"interestId"`
Name string `json:"name"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
// Many to many associations
UserProfiles []UserProfile `gorm:"many2many:user_interests;" json:"userProfiles"`
Threads []Thread `gorm:"many2many:thread_interests;" json:"threads"`
}
Since it is many to many between both structs I created another struct to act as join table named ThreadInterest. The code:
type ThreadInterest struct {
ThreadID uuid.UUID `gorm:"primaryKey;"`
InterestID uuid.UUID `gorm:"primaryKey;"`
CreatedAt time.Time
UpdatedAt time.Time
}
The problem is that whenever I create a new thread with the corresponding interests it creates the thread record but no new record is created in the join table ThreadInterest. I tried reading the documentation and searching online but I can't find a solution. I hope you guys could help me on this.
UPDATE: Here is how I create the thread
handler:
func HandleCreateThread(context *gin.Context) {
var threadInput apimodels.ThreadInput
err := context.ShouldBindJSON(&threadInput)
if err != nil {
// return error
context.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
userId, err := api.GetTokenUserId(context)
if err != nil {
// return error
context.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var interests []databasemodels.Interest
interests, err = dataaccess.FindInterestByIds(threadInput.Interests)
if err != nil {
context.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
thread := databasemodels.Thread{
Title: threadInput.Title,
Body: threadInput.Body,
Interests: interests,
UserID: userId,
}
newThread, err := dataaccess.CreateNewThread(&thread)
if err != nil {
context.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
context.JSON(http.StatusOK, gin.H{"thread": newThread})
}
dataaccess:
func CreateNewThread(thread *databasemodels.Thread) (*databasemodels.Thread, error) {
// Generate ID and hash password
thread.ID = api.GenerateUUID()
// store to database
err := database.Database.Create(&thread).Error
if err != nil {
return &(databasemodels.Thread{}), err
}
return thread, nil
}
And this is how I migrate my database:
var Database *gorm.DB
// start a connection to the specified postgresql db from env file
func ConnectDb() {
var err error
host := os.Getenv("DB_HOST")
username := os.Getenv("DB_USER")
password := os.Getenv("DB_PASSWORD")
databaseName := os.Getenv("DB_NAME")
port := os.Getenv("DB_PORT")
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Africa/Lagos", host, username, password, databaseName, port)
Database, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
} else {
fmt.Println("Successfully connected to the database")
}
}
// conducts migrations to the connected database (built-in GORM functionality)
func AutoMigrateDb() {
Database.AutoMigrate(
&(databasemodels.User{}),
&(databasemodels.UserProfile{}),
&(databasemodels.Interest{}),
&(databasemodels.UserInterest{}),
&(databasemodels.Comment{}),
&(databasemodels.Thread{}),
&(databasemodels.ThreadInterest{}),
&(databasemodels.PostLike{}),
&(databasemodels.PostDislike{}),
&(databasemodels.CommentLike{}),
&(databasemodels.CommentDislike{}),
)
}
Expected answer
Insert a new record storing both keys of the two structs that has a many to many relationship after creating thread.
Comment From: roskee
Hi, I ran your sample code and it works fine. Maybe check if FindInterestByIds is correctly returning its values.
Comment From: github-actions[bot]
This issue has been automatically marked as stale because it has been open 360 days with no activity. Remove stale label or comment or this will be closed in 180 days