问题
客户列表写好之后,在测试更新的时候遇到了一个问题
对一个客户详情没有进行改动之后点击保存(更新)会报
Duplicate entry 'xxxx' for key 'PRIMARY'"的错误。
但是Save相当于FirstOrCreate,因为我已经查询出了要更新的记录,并且有id,按理说这时候的Save等同于Update操作,为什么会报这种错呢?
看了Save的实现:
// Save update value in database, if the value doesn't have primary key, will insert it
func (s *DB) Save(value interface{}) *DB {
scope := s.NewScope(value)
if !scope.PrimaryKeyZero() {
newDB := scope.callCallbacks(s.parent.callbacks.updates).db
if newDB.Error == nil && newDB.RowsAffected == 0 {
return s.New().FirstOrCreate(value)
}
return newDB
}
return scope.callCallbacks(s.parent.callbacks.creates).db
}
注意这里的if newDB.Error == nil && newDB.RowsAffected == 0,在主键不为0的时候,会先进行更新的操作,如果更新返回的rowsAffected 为0才会去执行FirstOrCreate。
没有任何改动去更新的时候,rowsAffected为0,这时候进入FirstOrCreate,而FirstOrCreate的where语句中有deleted_at IS NULL,但是这里我的记录是已经被软删除过的,所以会创建新的记录,因此在这里就有主键冲突。
反之,如果有改动的时候因为rowsAffected不为0,那么就会正常的执行update。
解决办法
- 不用
Save,改用Update - 返回列表中不显示已经被删除过的用户