Your Question
let me explain the problem with an example i have user and course in many to many relationship. every user can buy many courses and a course can belong to many users every bought course has a expiration date on many to many relationship
type User struct {
...
Courses []*Course `gorm:"many2many:course_user;"`
}
type Course struct {
...
Users []*User `json:"-" gorm:"many2many:course_user;"`
}
type CourseUser struct {
// the gorm:foreignKey just creates a relationship between tables and works just fine
UserID int `gorm:"foreignKey:ID"`
CourseID int `gorm:"foreignKey:ID"`
ExpirationDate time.Time
}
it works in preload like this:
D.DB().Model(&user).
Preload("Courses").
Find(&user)
and returns the user with all of bought courses but when i want to preload only courses that their expiration_date is > now i like this i get error:
D.DB().Model(&user).
Preload("Courses", "expiration_date > ?", time.Now()).
Find(&user)
error:
ERROR: column "expiration_date" does not exist (SQLSTATE 42703)
SELECT * FROM "courses" WHERE "courses"."id" = 69 AND expiration_date > '2023-07-23 23:59:41.564'
Expected answer
preload all user's courses with many to many expiration_date > now with sql like this
SELECT * FROM "course_user" WHERE "course_user"."user_id" = 9 AND expiration_date > '2023-07-23 23:59:41.564'
Comment From: saeidee
You can use join and perload together.
Comment From: mostafa-binesh
You can use join and perload together.
Can you give me the code based on my example
Comment From: shanel262
@mostafa-binesh Did you ever find an answer to this? It still isn't properly documented and I've been searching for a solution all morning
Comment From: tomassommareqt
@mostafa-binesh same here.
Comment From: mostafa-binesh
it's been a while so i don't remember how i handled it but as far as i remember, you cannot join these tables easily, so you have to get the data directly from the many2many table and handle it accordingly, like this:
// i want all bought courses from user X. i cannot join it with user model, i have to get the bought courses ids first and then handle it accordingly
var courseIDs []uint
if err := D.DB().Model(&CourseUser{}).Where("user_id = ? AND expiration_date > ?", userID, time.Now()).
Pluck("course_id", &courseIDs).Error; err != nil {
return nil, err
}
@tomassommareqt @shanel262
Comment From: fari-99
@mostafa-binesh so it didn't use preload at all? but you collect the course id first, then on preload you put that on the conditions preload? seems strange to me, why we cant add conditions to preload many2many for that join table.