package controllers import ( "fmt" "net/http" "strconv" "github.com/gin-gonic/gin" "gorm.io/gorm" "example.com/gin/test/models" ) type CRUDController interface { Create(*gin.Context) GetAll(*gin.Context) GetById(*gin.Context) Update(*gin.Context) Delete(*gin.Context) } type RoomController interface { CRUDController GetUsers(*gin.Context) AddUser(*gin.Context) } type roomController struct { DB *gorm.DB } func NewRoomController(db *gorm.DB) RoomController { return &roomController{ DB: db, } } func (rc *roomController) GetAll(c *gin.Context) { var rooms []models.Room result := rc.DB.Find(&rooms) if result.Error != nil { ReplyError(c, fmt.Errorf("Could not query rooms")) return } c.JSON(http.StatusOK, rooms) } func (rc *roomController) GetById(c *gin.Context) { roomId, err := strconv.Atoi(c.Param("id")) if err != nil { ReplyError(c, fmt.Errorf("Room with Id '%s' does not exist", c.Param("id"))) return } var room models.Room result := rc.DB.First(&room, uint(roomId)) if result.Error != nil { ReplyError(c, fmt.Errorf("Could not query room: %v", result.Error)) return } ReplyOK(c, room) } func (rc *roomController) Create(c *gin.Context) { user, exists := c.Get("user") if !exists { c.AbortWithStatus(http.StatusUnauthorized) return } room, err := models.NewRoom(c) room.Admins = append(room.Admins, user.(models.User)) if err != nil { ReplyError(c, err) } result := rc.DB.Create(&room) if result.Error != nil { ReplyError(c, fmt.Errorf("Room creation failed: %s", result.Error)) return } //userID := user.(models.User).ID //rc.DB.Model(&models.Room{}).Where("id = ?"), room.ID).Association("Admins").Append(&models.User{ID: userID}) //if result.Error != nil { // ReplyError(c, fmt.Errorf("Room creation failed: %s", result.Error)) // return //} ReplyOK(c, "Room was created") } func (rc *roomController) Update(c *gin.Context) { roomId, err := strconv.Atoi(c.Param("id")) if err != nil { ReplyError(c, fmt.Errorf("Room with Id '%s' does not exist", c.Param("id"))) return } room, err := models.NewRoom(c) if err != nil { ReplyError(c, err) return } room.ID = uint(roomId) result := rc.DB.Save(&room) if result.Error != nil { ReplyError(c, fmt.Errorf("Room creation failed: %s", result.Error)) return } ReplyOK(c, "Room was updated") } func (rc *roomController) Delete(c *gin.Context) { roomId, err := strconv.Atoi(c.Param("id")) if err != nil { ReplyError(c, fmt.Errorf("Room with Id '%s' does not exist", c.Param("id"))) return } result := rc.DB.Delete(&models.Room{}, roomId) if result.Error != nil { ReplyError(c, fmt.Errorf("Room deletion failed: %s", result.Error)) return } ReplyOK(c, "Room was deleted") } func (rc *roomController) GetUsers(c *gin.Context) { //only allow room admin roomId, err := strconv.Atoi(c.Param("id")) if err != nil { ReplyError(c, fmt.Errorf("Room with Id '%s' does not exist", c.Param("id"))) return } var room models.Room result := rc.DB.First(&room, uint(roomId)) if result.Error != nil { ReplyError(c, fmt.Errorf("Could not query room: %v", result.Error)) return } var users []models.User rc.DB.Model(&room).Association("Users").Find(&users) var emails []string for _, user := range users { emails = append(emails, user.Email) } ReplyOK(c, emails) } func (rc *roomController) AddUser(c *gin.Context) { //only allow room admin var body struct { Email string } err := c.Bind(&body) if err != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Failed to read body", }) return } //lookup requested user var user models.User result := rc.DB.First(&user, "email = ?", body.Email) if result.Error != nil { c.JSON(http.StatusBadRequest, gin.H{ "error": "Invalid user", }) return } roomId, err := strconv.Atoi(c.Param("id")) if err != nil { ReplyError(c, fmt.Errorf("Room with Id '%s' does not exist", c.Param("id"))) return } var room models.Room result = rc.DB.First(&room, uint(roomId)) if result.Error != nil { ReplyError(c, fmt.Errorf("Could not query room: %v", result.Error)) return } rc.DB.Model(&room).Association("Users").Append(&user) ReplyOK(c, "Added User to Room") } func ReplyError(ctx *gin.Context, err error) { ctx.JSON(http.StatusBadRequest, gin.H{ "error": err.Error() }) } func ReplyOK(ctx *gin.Context, message any) { ctx.JSON(http.StatusOK, message) }