How to Update Multiple Records Using gorm?

Viewed 36

So I want to update movie_genre data with different genre_id values, each movie has more than 1 genre_id automatically there are multiple records in movie_genre with the same movie_id and different genre_id,

when I start trying to update with gorm by selecting only 1 genre_id, the old genre has changed, but the newly changed genre is created again in a new row with all the same column values ​​except created_at, whereas if I try to update by selecting 2 genres, the data the changed only has the value of the first genre_id, the second genre_id is not read

this is a erd database

enter image description here

payload json from frontend

{
  "title":"Autaaa sint nihil quis ",
  "release_date":"2001-01-01",
  "runtime":"22",
  "mpaa_rating":"G",
  "rating":"4",
  "description":"Eius enim distinctio1",
  "id":"82",
  "genre_id":["3","8"]
}: 

handler

func (app *Application) UpdateMovie(ctx *gin.Context) {

    var payload web.MoviePayloadResponse
    if err := ctx.BindJSON(&payload); err != nil {
        log.Println(err)
        return
    }

    id, _ := strconv.Atoi(payload.ID)
    movie, err := app.models.Repository.GetMovieById(id)
    if err != nil {
        helper.NotFound(*ctx, err)
        return
    }

    movie.ID, _ = strconv.Atoi(payload.ID)
    movie.Title = payload.Title
    movie.Description = payload.Description
    movie.ReleaseDate, _ = time.Parse("2006-01-02", payload.ReleaseDate)
    movie.Year = movie.ReleaseDate.Year()
    movie.Runtime, _ = strconv.Atoi(payload.Runtime)
    movie.Rating, _ = strconv.Atoi(payload.Rating)
    movie.MPAARating = payload.MPAARating
    movie.UpdatedAt = time.Now()
    
    err = app.models.Repository.UpdateMovie(movie, id)
    if err != nil {
        panic(err)
    }


    movieGenre, _ := app.models.Repository.GetMovieGenresById(id)
    
    for _, mg := range *movieGenre {
        mg.MovieID = movie.ID
        mg.UpdatedAt = time.Now()
        for _, v := range payload.GenreID {
            mg.GenreID, _ = strconv.Atoi(v)
            err := app.models.Repository.UpdateMovieGenre(&mg, id)
            if err != nil {
                panic(err)
            }
        }
    }

    ctx.JSON(http.StatusOK, &gin.H{
        "ok": "response",
    })

    return
}

repository

func (MovieRepositoryImpl *MovieRepositoryImpl) UpdateMovie(movie *Movie, id int) error {
    err := MovieRepositoryImpl.DB.Where("id = ?", id).Save(&movie).Error
    if err != nil {
        return err
    }
    return nil
}

func (MovieRepositoryImpl *MovieRepositoryImpl) UpdateMovieGenre(movieGenre *MovieGenre, id int) error {
    err := MovieRepositoryImpl.DB.Where("movie_id = ?", id).Save(&movieGenre).Error
    if err != nil {
        return err
    }
    return nil
}

func (MovieRepositoryImpl *MovieRepositoryImpl) GetMovieGenresById(id int) (*[]MovieGenre, error) {
    var movie []MovieGenre
    err := MovieRepositoryImpl.DB.Where("movie_id = ?", id).Find(&movie).Error
    if err != nil {
        return nil, err
    }
    
    return &movie, nil
}

Model

type Movie struct {
    ID          int          `json:"id"`
    Title       string       `json:"title"`
    Description string       `json:"description"`
    Year        int          `json:"year"`
    ReleaseDate time.Time    `json:"release_date"`
    Runtime     int          `json:"runtime"`
    Rating      int          `json:"rating"`
    MPAARating  string       `json:"mpaa_rating"`
    CreatedAt   time.Time    `json:"created_at"`
    UpdatedAt   time.Time    `json:"updated_at"`
    Genres      []Genre      `json:"genres" gorm:"many2many:movie_genres"`
    MovieGenre  []MovieGenre `json:"movie_genres" gorm:"many2many:movie_genres"`
}

type Genre struct {
    ID        int       `json:"id"`
    GenreName string    `json:"name"`
    Movies    []Movie   `json:"movies" gorm:"many2many:movie_genres"`
    CreatedAt time.Time `json:"-"`
    UpdatedAt time.Time `json:"-"`
}

type MovieGenre struct {
    ID        int       `json:"id"`
    MovieID   int       `json:"movie_id"`
    Movie     Movie     `gorm:"foreignKey:MovieID"`
    GenreID   int       `json:"genre_id"`
    Genre     Genre     `gorm:"foreignKey:GenreID"`
    CreatedAt time.Time `json:"-"`
    UpdatedAt time.Time `json:"-"`
}

type MoviePayloadResponse struct {
    ID          string   `json:"id"`
    Title       string   `json:"title"`
    Description string   `json:"description"`
    Year        string   `json:"year"`
    ReleaseDate string   `json:"release_date"`
    Runtime     string   `json:"runtime"`
    Rating      string   `json:"rating"`
    MPAARating  string   `json:"mpaa_rating"`
    GenreID     []string `json:"genre_id"`
    CreatedAt   string   `json:"created_at"`
    UpdatedAt   string   `json:"updated_at"`
}

My expectation is that the data genre_id that changes is only data whose value is not the same as the value in the payload, if it is the same then the data does not change, if it is different then it changes, and if the data in the payload exceeds the original genre data, then new data is automatically created. That's roughly what it looks like. Please help!!

0 Answers
Related