更新字段将创建新的外键项,而不是对其进行更新

I've got a one-to-one relationship, Location, working with postgresql:

type App struct {
    gorm.Model

    PersoID      string `gorm:"primary_key;unique" json:"perso_id"`

    Location   OllyLocation `gorm:"foreignkey:location_id"`
    LocationID *uint        `json:"-" gorm:"type:integer REFERENCES locations(id)"`

    Users          []User       `json:"users,omitempty" gorm:"many2many:app_users;"`
}

type Location struct {
    ID        uint      `json:"-" gorm:"primary_key;unique"`
    CreatedAt time.Time `json:"-"`
    UpdatedAt time.Time

    Lat         float64 `json:"lat"`
    Long        float64 `json:"long"`
    Address     string  `json:"address"`
    Country     string  `json:"country"`
}

But as you can see, the App structure has its own primaryKey id as string (and the GORM one). Thus this block from doing a simple db.Save() from gorm.

So I've tried to do:

func (previousModel *App) UpdateAndReturnedUpdated(db *gorm.DB, appUpdated *App) error {
    if err := db.Model(previousModel).Update(appUpdated).Error; err != nil {
        return err
    }

    return db.Preload("Location").First(previousModel, App{PersoID: appUpdated.PersoID}).Error
}

With this, the App is correctly updated - fantastic! - but not the Location.

The location is re created in the db with the new values and the foreignKey LocationID is updated on the App.

This is super annoying because if I want to do an update of the address only without specifying other fields, they are just re created with the original type value (lat / long will be 0)

Any ideas about how to update the foreignKey? Thanks!

You can use this to not modify the associated entities

db.Set("gorm:save_associations", false).Save(previousModel)

or to save only one field of the struct

db.Model(previousModel).UpdateColumn("PersoID", appUpdated.PersoID)

if you want to update an associated entity and not the relation you will need to update the entity itself

db.Model(Location{ID:*previousModel.LocationID}).Update(appUpdated.Location)

Well, once more (but let's not blame the guy, he is alone) the main problem comes from an incomplete documentation.

All my problems were solved when I checked that I properly preloaded my foreign object + indicate it's ID (which blocked the fact that the foreignKey was Inserted instead of Updated)

Then, to be able to update it properly I had to do:

db.
    Model(previousModel).
    UpdateColumns(appUpdated).
    Model(&previousModel.Location).
    Updates(appUpdated.Location)

Was very painful, but at least it's solved.