Search code examples
postgresqlgoassociationsgo-gorm

Update HasMany Association failing Gorm


When I try to update the Shoppinglist struct with the data I get an "there is no unique or exclusion constraint matching the ON CONFLICT specification (SQLSTATE 42P10)" Error

These are my Structs

type Shoppinglist struct {
    Model

    ID           int            `gorm:"primaryKey" json:"id"`
    Title        string         `json:"title"`
    Items        []Item         `json:"items" gorm:"foreignKey:ParentListID;references:ID;"`
    Owner        string         `json:"owner"`
    Participants pq.StringArray `gorm:"type:text[]" json:"participants"`
}

type Item struct {
    Model

    ParentListID int    `gorm:"primaryKey" json:"parentListId"`
    Title        string `json:"title"`
    Position     int    `json:"position"`
    Bought       bool   `json:"bought"`
}

And this is the Code I execute when trying to edit a list

func EditList(id int, data map[string]interface{}) error {
    //https://github.com/go-gorm/gorm/issues/3487

    shoppinglist := Shoppinglist{
        ID:           data["id"].(int),
        Title:        data["title"].(string),
        Items:        data["items"].([]Item),
        Owner:        data["owner"].(string),
        Participants: data["participants"].([]string),
    }

    if err := db.Session(&gorm.Session{FullSaveAssociations: true}).Where("id = ?", id).Updates(&shoppinglist).Error; err != nil {
        return err
    }

    return nil
}

This is where I execute the EditList and where I set all the values to pass nito the map:

type Shoppinglist struct {
    ID           int
    Title        string
    Items        []models.Item
    Owner        string
    Participants []string
    PageNum      int
    PageSize     int
}

func (s *Shoppinglist) Edit() error {
    shoppinglist := map[string]interface{}{
        "id":           s.ID,
        "title":        s.Title,
        "items":        s.Items,
        "owner":        s.Owner,
        "participants": s.Participants,
    }

    return models.EditList(s.ID, shoppinglist)
}

Before I was just using a []string instead of []Item and that was working perfectly. Now everything updates except for the []Item

These are the SQL Queries executed:

UPDATE "shoppinglists" SET "modified_on"=1628251977096,"title"='kjhdsfgnb',"owner"='[email protected]',"participants"='{}' WHERE id = 517687 AND "id" = 517687

INSERT INTO "items" ("created_on","modified_on","deleted_at","title","position","bought","parent_list_id") VALUES (1628251977,1628251977116,NULL,'dfkjhgndfjkg',1,false,517687),(1628251977,1628251977116,NULL,'dfgh123',2,true,517687) ON CONFLICT ("parent_list_id") DO UPDATE SET "created_on"="excluded"."created_on","modified_on"="excluded"."modified_on","deleted_at"="excluded"."deleted_at","title"="excluded"."title","position"="excluded"."position","bought"="excluded"."bought" RETURNING "parent_list_id"

I would really like to know how to Update a Relation in Gorm or why this isn't working because I've been looking through all the Association Issues on Github and Stackoverflow and didn't find a answer that worked for me.


Solution

  • The first problem I see here is that your Item has no ID but uses the ParentListID as primary key. That means you can only have one Item for each parent which defeats the purpose of having an array.

    Create an ID field (used as primary key) for items and if there's still issues with your approach, please update the question.

    PS: would have left this in a comment, but can't.