doudun1029 2018-11-05 18:37
浏览 5

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

I want to make sure my query to find models by ID is correct as I will be using this same pattern for all my structs/models.

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
}

So a common usecase in a web application is to lookup a model, if it does not exist that I will insert a new record.

using the above I will do:

user, err := GetUserLocationById(123)
if err != nil {
  err := InsertNewUser(user)
}

Now what thing I am struggling with is this. If the errors is not nil, then I should insert a new user. But what if the error is because my query inside the function GetUserLocationById has the wrong column name? I dont' want to start inserting rows when they really do exist.

Looking for some advice to make sure I am doing this correctly.

  • 写回答

1条回答 默认 最新

  • duanfan8699 2018-11-05 19:06
    关注

    Regarding "best practices", it's better to post under 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
    }
    

    Okay this is closer to the GO "best practices" standards IMHO. It's considered good practices to create package error values for commonly returned errors. It helps the caller handle each case properly (should there be), but it's not really the case here.

    For the other snippet, you really won't want to do this like that. First of all you omitted the pointer receiver for both methods GetUserLocationById and InsertNewUser. Then, you usually don't want to shadow the parent's scope err variable, but it's ok here...

    user, err := dbs.GetUserLocationById(123)
    if err != nil {
       err = dbs.InsertNewUser(user)
       // handle err here
    }
    

    Anyways, I think that doing this with errors is too bad for there are no really other possibilities than "ErrUserNotFound" here. I would advise going for a ok boolean instead.

    func (dbs *DbService) GetUserLocationId(locationId int) (user User, ok bool)
        record := dbs.deps.db.Where("location_id = ?", locationId).Find(&user)
        ok = !record.RecordNotFound()
        return
    }
    

    and then

    var user User
    if user, ok := dbs.GetUserLocationId(123); !ok {
        if err := dbs.InsertNewUser(user); err != nil {
            panic(err)
        }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化结果不一致
  • ¥20 求用stm32f103c6t6在lcd1206上显示Door is open和password:
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法