我想确保通过ID查找模型的查询正确无误,因为我将对所有结构/模型使用相同的模式。
func (dbs *DbService) GetUserLocationId(locationId int) (User, error) {
var model User
if dbs.deps.db.Where("location_id = ?", locationId).Find(&model).RecordNotFound() {
return model, errors.New("User not found")
}
return model, nil
}
因此,在Web应用程序中,一个常见用例是查找模型,如果不存在,我将插入新记录。
使用上述方法,我会这样做:
user, err := GetUserLocationById(123)
if err != nil {
err := InsertNewUser(user)
}
现在我正在努力的是什么。如果错误不是nil,那么我应该插入一个新用户。但是,如果错误是因为我的函数GetUserLocationById中的查询具有错误的列名怎么办? 我不想在行确实存在时开始插入行。
正在寻找一些建议,以确保我正确执行此操作。
答案 0 :(得分:2)
关于“最佳做法”,最好在the dedicated SO website下发布。
var ErrUserNotFound = errors.New("User not found")
func (dbs *DbService) GetUserLocationId(locationId int) (user User, err error)
record := dbs.deps.db.Where("location_id = ?", locationId).Find(&user)
if record.RecordNotFound() {
err = ErrUserNotFound
}
return
}
好的,这更接近于IMHO的GO“最佳实践”标准。为常见返回的错误创建包错误值被认为是一种好习惯。它可以帮助呼叫者正确地处理每种情况(应该有),但实际上情况并非如此。
对于其他代码段,您确实不想这样做。首先,您省略了方法GetUserLocationById
和InsertNewUser
的指针接收器。然后,您通常不想隐藏父级的范围err
变量,但是在这里 ok ...
user, err := dbs.GetUserLocationById(123)
if err != nil {
err = dbs.InsertNewUser(user)
// handle err here
}
无论如何,我认为带有错误的操作实在是太糟糕了,因为这里除了“ ErrUserNotFound”之外没有其他可能性。我建议改用ok
布尔值。
func (dbs *DbService) GetUserLocationId(locationId int) (user User, ok bool)
record := dbs.deps.db.Where("location_id = ?", locationId).Find(&user)
ok = !record.RecordNotFound()
return
}
然后
var user User
if user, ok := dbs.GetUserLocationId(123); !ok {
if err := dbs.InsertNewUser(user); err != nil {
panic(err)
}
}