Maison  >  Article  >  développement back-end  >  Clés étrangères dans GORM non mises à jour

Clés étrangères dans GORM non mises à jour

WBOY
WBOYavant
2024-02-09 11:57:071051parcourir

GORM 中的外键未更新

Lorsque j'utilisais GORM récemment, j'ai trouvé un problème : les clés étrangères n'étaient pas mises à jour. Lorsque j'ai mis à jour la valeur du champ de clé étrangère dans la table associée, elle n'a pas été mise à jour de manière synchrone avec l'autre table. Grâce à des enquêtes et des recherches, j'ai découvert que cela était dû au fait que GORM ne met pas automatiquement à jour les champs de clé étrangère par défaut. Ce problème me dérange depuis un moment, j'ai donc décidé de partager la solution avec tout le monde. Dans cet article, je vais vous montrer comment utiliser GORM pour mettre à jour correctement les champs de clé étrangère afin d'éviter ce problème.

Contenu de la question

J'ai deux bureaux, l'un est une entreprise

type Company struct {
    Id        uuid.UUID `gorm:"column:id;primaryKey;"`
    CreatedAt time.Time `gorm:"index;column:createdAt"`
    UpdatedAt time.Time `gorm:"index;column:updatedAt"`
    Name      string    `gorm:"column:name" binding:"required"`
}

L'autre est product_entitlement

type ProductEntitlement struct {
ID        uuid.UUID
CreatedAt time.Time `gorm:"index;column:createdAt"`
UpdatedAt time.Time `gorm:"index;column:updatedAt"`
Type       string    `gorm:"column:type" binding:"required"`
CompanyID  uuid.UUID `gorm:"column:companyId;size:36"`
Company    Company   `gorm:"foreignKey:CompanyID"`
}

CompanyID est une clé étrangère. CompanyID contient la valeur de Company.Id

Une fois l'insertion de mise à jour terminée, de nouvelles lignes seront insérées à chaque fois. C'est le code que nous utilisons

func UpdateEntitlement(c *gin.Context) {
cid := c.Param("companyId")
    id := c.Param("entitlementId")
    eid := uuid.MustParse(id)
    log.Println(eid)
    uid := uuid.MustParse(cid)
    log.Println(uid)
    var entitlementRequest entities.ProductEntitlement
    if err := c.BindJSON(&entitlementRequest); err != nil {
        log.Println(err)
        fmt.Println("ERROR: ", err)
        c.JSON(400, gin.H{"error": "Invalid JSON format"})
        return
    }
    if err := database.DB.Clauses(clause.OnConflict{
        Columns:   []clause.Column{{Name: "id"}},
        UpdateAll: true,
    }).Create(&entitlementRequest).Error; err != nil {
        log.Println(err)
    }
}

Mais cela échoue toujours et donne une erreur

BD820BD3F94A2A45E18ED8E8094EF395

Je souhaite mettre à jour Product_entitlement si l'ID existe, sinon créez-en un nouveau

L'URL est la suivante, http://localhost:8080/company/{{companyId}}/product/{{companyId}} et utilisez la méthode PUT Le corps est

{"type": "auto"}

Solution de contournement

Si cela aide quelqu'un, nous pouvons utiliser la fonction FirstOrCreate pour vérifier si l'identifiant existe et le mettre à jour, sinon en créer un nouveau.

Pour attribuer une clé étrangère, nous devons attribuer la valeur à la table associée,

entitlementRequest.CompanyID = uid

func UpdateEntitlement(c *gin.Context) {
    cid := c.Param("companyId")
    uid := uuid.MustParse(cid)
    eid := c.Param("entitlementId")
    nid := uuid.MustParse(eid)
    var entitlementRequest entities.ProductEntitlement
    entitlementRequest.CompanyID = uid

    if err := c.BindJSON(&entitlementRequest); err != nil {
        fmt.Println("ERROR: ", err)
        c.JSON(400, gin.H{"error": "Invalid JSON format"})
        return
    }
    if err := database.DB.Where("id = ?", nid).
        Assign(entitlementRequest).
        FirstOrCreate(&entitlementRequest).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Record not found!"})
        return
    }
    c.JSON(http.StatusOK, gin.H{"error": "Product entitlement upserted successfully"})
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer