我的查找功能是否遵循最佳实践

时间:2018-11-05 18:37:37

标签: go go-gorm

我想确保通过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中的查询具有错误的列名怎么办? 我不想在行确实存在时开始插入行。

正在寻找一些建议,以确保我正确执行此操作。

1 个答案:

答案 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“最佳实践”标准。为常见返回的错误创建包错误值被认为是一种好习惯。它可以帮助呼叫者正确地处理每种情况(应该有),但实际上情况并非如此。

对于其他代码段,您确实不想这样做。首先,您省略了方法GetUserLocationByIdInsertNewUser的指针接收器。然后,您通常不想隐藏父级的范围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)
    }
}