From 1f87df43a8f43f70e950d2eb736a0e6721025ce1 Mon Sep 17 00:00:00 2001 From: celogeek Date: Sun, 6 Feb 2022 15:54:12 +0100 Subject: [PATCH] create album with recursive display --- internal/photos/api/album.go | 33 ++++++++++++++++++++++++++----- internal/photos/api/errors.go | 3 +++ internal/photos/models/account.go | 12 +++++------ internal/photos/models/album.go | 32 ++++++++++++++++++++---------- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/internal/photos/api/album.go b/internal/photos/api/album.go index 0a15523..3d94cdb 100644 --- a/internal/photos/api/album.go +++ b/internal/photos/api/album.go @@ -1,11 +1,14 @@ package api import ( + "errors" "net/http" "github.com/gin-gonic/gin" "gitlab.celogeek.com/photos/api/internal/photos/models" "gopkg.in/validator.v2" + "gorm.io/gorm" + "gorm.io/gorm/clause" ) type AlbumCreateRequest struct { @@ -25,13 +28,33 @@ func (s *Service) AlbumCreate(c *gin.Context) { sess := s.CurrentSession(c) - album := &models.Album{ - Name: req.Name, - ParentId: req.Parent, - AuthorId: &sess.AccountId, + var parentAlbum *models.Album + + if req.Parent != nil { + parentAlbum = &models.Album{} + if err := s. + DB. + Debug(). + Preload("Author"). + Find(parentAlbum, req.Parent).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + s.Error(c, http.StatusNotFound, ErrAlbumDontExists) + } else { + s.Error(c, http.StatusInternalServerError, err) + } + return + } } - if err := s.DB.Create(album).Error; err != nil { + album := &models.Album{ + Name: req.Name, + Parent: parentAlbum, + ParentId: req.Parent, + Author: sess.Account, + AuthorId: &sess.Account.ID, + } + + if err := s.DB.Debug().Omit(clause.Associations).Clauses(clause.Returning{}).Create(album).Error; err != nil { s.Error(c, http.StatusConflict, err) return } diff --git a/internal/photos/api/errors.go b/internal/photos/api/errors.go index a17b342..766dccc 100644 --- a/internal/photos/api/errors.go +++ b/internal/photos/api/errors.go @@ -22,6 +22,9 @@ var ( // Panic ErrUnexpected = errors.New("an unexpected error occur") + + // Album + ErrAlbumDontExists = errors.New("album doesn't exists") ) func (s *Service) Error(c *gin.Context, code int, err error) { diff --git a/internal/photos/models/account.go b/internal/photos/models/account.go index 7d42514..f7b0f6f 100644 --- a/internal/photos/models/account.go +++ b/internal/photos/models/account.go @@ -9,12 +9,12 @@ import ( ) type Account struct { - ID uint32 `gorm:"primary_key"` - Login string `gorm:"unique;size:64;not null"` - Password string `gorm:"-"` - EncryptedPassword string `gorm:"size:44;not null"` - CreatedAt time.Time - UpdatedAt time.Time + ID uint32 `gorm:"primary_key" json:"-"` + Login string `gorm:"unique;size:64;not null" json:"login"` + Password string `gorm:"-" json:"-"` + EncryptedPassword string `gorm:"size:44;not null" json:"-"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"-"` } func (a *Account) BeforeCreate(tx *gorm.DB) error { diff --git a/internal/photos/models/album.go b/internal/photos/models/album.go index 83f623d..6e286d1 100644 --- a/internal/photos/models/album.go +++ b/internal/photos/models/album.go @@ -1,15 +1,27 @@ package models -import "time" +import ( + "time" + + "gorm.io/gorm" +) type Album struct { - ID uint32 `gorm:"primary_key"` - Name string `gorm:"not null"` - Parent *Album `gorm:"constraint:OnDelete:SET NULL,OnUpdate:CASCADE"` - ParentId *uint32 - Author *Account `gorm:"constraint:OnDelete:SET NULL,OnUpdate:CASCADE"` - AuthorId *uint32 - Photos []*Photo `gorm:"many2many:album_photos"` - CreatedAt time.Time - UpdatedAt time.Time + ID uint32 `gorm:"primary_key" json:"id"` + Name string `gorm:"not null" json:"name"` + Parent *Album `gorm:"constraint:OnDelete:SET NULL,OnUpdate:CASCADE" json:"parent"` + ParentId *uint32 `json:"-"` + Author *Account `gorm:"constraint:OnDelete:SET NULL,OnUpdate:CASCADE" json:"author"` + AuthorId *uint32 `json:"-"` + Photos []*Photo `gorm:"many2many:album_photos" json:"-"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +func (a *Album) AfterFind(tx *gorm.DB) error { + if a.ParentId != nil { + a.Parent = &Album{} + return tx.Preload("Author").First(a.Parent, a.ParentId).Error + } + return nil }