"Creation At" time in GORM Customise Join table

Viewed 786

I am trying to customize many2many table join. I have two tables from which I want to have taken the ids and want another field, which will tell me when the entry in the join table was made. The ids are coming fine, but the "created_at" is not updating and shows "Null" instead of time.

// this is the table join struct which I want to make
type UserChallenges struct {
    gorm.JoinTableHandler
    CreatedAt   time.Time
    UserID      int
    ChallengeID int
}

//hook before create
func (UserChallenges) BeforeCreate(Db \*gorm.DB) error {
    Db.SetJoinTableHandler(&User{}, "ChallengeId", &UserChallenges{})
    return nil
}

This is not giving any error on the build. Please tell me what I am missing so that I can get the creation time field in this.

PS - The documentation of GORM on gorm.io is still showing SetupJoinTable method but it is deprecated in the newer version. There is a SetJoinTableHandler but there is no documentation available for it anywhere.

1 Answers

The thing to get about using a Join Table model is that if you want to access fields inside the model, you must query it explicitly.

That is using db.Model(&User{ID: 1}).Association("Challenges").Find(&challenges) or db.Preload("Challenges").Find(&users), etc. will just give you collections of the associated struct and in those there is no place in which to put the extra fields!

For that you would do:

joins := []UserChallenges{}
db.Where("user_id = ?", user.ID).Find(&joins)
// now joins contains all the records in the join table pertaining to user.ID,
// you can access joins[i].CreatedAt for example.

If you wanted also to retrieve the Challenges with that, you could modify your join struct to integrate the BelongsTo relation that it has with Challenge and preload it:

type UserChallenges struct {
    UserID      int `gorm:"primaryKey"`
    ChallengeID int `gorm:"primaryKey"`
    Challenge   Challenge
    CreatedAt   time.Time
}

joins := []UserChallenges{}
db.Where("user_id = ?", user.ID).Joins("Challenge").Find(&joins)
// now joins[i].Challenge is populated 
Related