package models import ( "strings" "time" "code.nonshy.com/nonshy/website/pkg/log" "gorm.io/gorm" ) // ForumMembership table. type ForumMembership struct { ID uint64 `gorm:"primaryKey"` UserID uint64 `gorm:"index"` User User `gorm:"foreignKey:user_id"` ForumID uint64 `gorm:"index"` Forum Forum `gorm:"foreignKey:forum_id"` Approved bool `gorm:"index"` IsModerator bool `gorm:"index"` CreatedAt time.Time UpdatedAt time.Time } // Preload related tables for the forum (classmethod). func (f *ForumMembership) Preload() *gorm.DB { return DB.Preload("User").Preload("Forum") } // CreateForumMembership subscribes the user to a forum. func CreateForumMembership(user *User, forum *Forum) (*ForumMembership, error) { var ( f = &ForumMembership{ User: *user, Forum: *forum, Approved: true, } result = DB.Create(f) ) return f, result.Error } // GetForumMembership looks up a forum membership. func GetForumMembership(user *User, forum *Forum) (*ForumMembership, error) { var ( f = &ForumMembership{} result = f.Preload().Where( "user_id = ? AND forum_id = ?", user.ID, forum.ID, ).First(&f) ) return f, result.Error } // IsForumSubscribed checks if the current user subscribes to this forum. func IsForumSubscribed(user *User, forum *Forum) bool { f, _ := GetForumMembership(user, forum) return f.UserID == user.ID } // Delete a forum membership. func (f *ForumMembership) Delete() error { return DB.Delete(f).Error } // PaginateForumMemberships paginates over a user's ForumMemberships. func PaginateForumMemberships(user *User, pager *Pagination) ([]*ForumMembership, error) { var ( fs = []*ForumMembership{} query = (&ForumMembership{}).Preload() wheres = []string{} placeholders = []interface{}{} ) query = query.Where( strings.Join(wheres, " AND "), placeholders..., ).Order(pager.Sort) query.Model(&ForumMembership{}).Count(&pager.Total) result := query.Offset(pager.GetOffset()).Limit(pager.PerPage).Find(&fs) return fs, result.Error } // ForumMembershipMap maps table IDs to Likes metadata. type ForumMembershipMap map[uint64]bool // Get like stats from the map. func (fm ForumMembershipMap) Get(id uint64) bool { return fm[id] } // MapForumMemberships looks up a user's memberships in bulk. func MapForumMemberships(user *User, forums []*Forum) ForumMembershipMap { var ( result = ForumMembershipMap{} forumIDs = []uint64{} ) // Initialize the result set. for _, forum := range forums { result[forum.ID] = false forumIDs = append(forumIDs, forum.ID) } // Map the forum IDs the user subscribes to. var followIDs = []uint64{} if res := DB.Model(&ForumMembership{}).Select( "forum_id", ).Where( "user_id = ? AND forum_id IN ?", user.ID, forumIDs, ).Scan(&followIDs); res.Error != nil { log.Error("MapForumMemberships: %s", res.Error) } for _, forumID := range followIDs { result[forumID] = true } return result }