Replies: 1 comment
|
GORM's Why the struct tags fail:
For a standard single many-to-many (one join table), this works: type User struct {
Roles []Role `gorm:"many2many:user_roles;"`
}
db.Preload("Roles", func(db *gorm.DB) *gorm.DB {
return db.Where("server_id = ?", serverID)
}).First(&user, id)The scope function filters within GORM's generated query, so it works cleanly. For two join tables (your case): GORM can't natively express this relationship. Manual fetching is the correct approach and is perfectly idiomatic: func (r *UserRepo) FindWithRoles(ctx context.Context, userID, serverID int) (*User, error) {
var user User
if err := r.db.WithContext(ctx).First(&user, userID).Error; err != nil {
return nil, err
}
var roles []Role
err := r.db.WithContext(ctx).
Table("roles").
Joins("JOIN user_role_assignments ura ON ura.role_id = roles.id AND ura.user_id = ?", userID).
Joins("JOIN server_assignments sa ON sa.id = ura.server_assignment_id AND sa.server_id = ?", serverID).
Find(&roles).Error
if err != nil {
return nil, err
}
user.Roles = roles
return &user, nil
}Mark the struct field as This approach is explicit, testable, and doesn't fight GORM's preload mechanism. |
Uh oh!
There was an error while loading. Please reload this page.
I'm trying to create a custom
Preload(). I need a custom preload because I have to take two many to many tables into account when pulling in the data. Something like this:then
However it seems no matter what tag I add to the struct my preload won't work.
I'm not able to do something like this as I have two many to many tables that I need to take into account (hence the need for the custom Preload in the first place).
`gorm:"->;many2many:"`Maybe the only solution here is to manually fetch and add the data after the query? If that's the case I can do that; I had just wanted to use the
Preload()as it's a bit cleaner code-wise.All reactions