Open utterances-bot opened 3 years ago
db = db.Where("state = ?", t.State)
if err := db.Model(&t).Where("is_del = ?", 0).Count(&count).Error; err != nil {
return 0, err
}
这里 err的赋值写法看着好奇怪啊
db = db.Where("state = ?", t.State) if err := db.Model(&t).Where("is_del = ?", 0).Count(&count).Error; err != nil { return 0, err }
这里 err的赋值写法看着好奇怪啊
@RanchoCooper 不奇怪,现实企业项目中很多开发者爱这么写。一般如果对变量 err 需要有其他处理,才会单独处理。
2.6.2 处理 model 回调部分
新版的gorm找不到gorm.Scope
2.6.2 处理 model 回调部分
新版的gorm找不到
gorm.Scope
@RanchoCooper 由于本文,在拉取 gorm 时已经限定了 v1 的版本(当时 v2 还在 beta)。因此是不支持 gorm v2 的。等后续如果第四次印刷的话,才会考虑正式支持 gorm v2。
如果是按自己个人意愿拉取了 v2,那就自行适配就好了。适配好了可以把所属代码在评论区上留下言,让更多小伙伴学习,谢谢。
我跟着博客写到这里 发现创建的钩子函数未生效,而更新和删除的钩子函数生效了,请问下这有可能是什么原因 。。。 db.Callback().Create().Replace("gorm:update_timestamp", updateTimeStampForCreateCallback) 。。。 func updateTimeStampForCreateCallback(scope *gorm.Scope) { if !scope.HasError() { fmt.Printf("scope has no error") nowTime := time.Now().Unix() if createTimeField, ok := scope.FieldByName("CreatedOn"); ok { if createTimeField.IsBlank { = createTimeField.Set(nowTime) } }
if modifyTimeField, ok := scope.FieldByName("ModifiedOn"); ok {
if modifyTimeField.IsBlank {
_ = modifyTimeField.Set(nowTime)
}
}
}
}
这个错误有xd遇到过没 runtime error: invalid memory address or nil pointer dereference ... /go-playground/universal-translator@v0.17.0/translator.go:335 (0x8b619a) (translator).C: b = append(b, trans.text[:trans.indexes[0]]...) **/go-playground/validator/v10@v10.6.1/translations/zh/zh.go:184 (0xc2a315) RegisterDefaultTranslations.func4: c, err = ut.C("min-string-character", f64, digits, ut.FmtNumber(f64, digits)) /go-playground/validator/v10@v10.6.1/errors.go:274 (0x8efe82) (*fieldError).Translate: return fn(ut, fe) /go-playground/validator/v10@v10.6.1/errors.go:76 (0x8ef975) ValidationErrors.Translate: trans[fe.ns] = fe.Translate(ut) /go-programming-tour-book/blog-service/pkg/app/form.go:44 (0xbe8b55) BindAndValid: for key, value := range verrs.Translate(trans) { ***/go-programming-tour-book/blog-service/internal/routers/api/v1/tag.go:104 (0xc33d84) Tag.Update: valid, errs := app.BindAndValid(c, ¶m) ...
for key, value := range verrs.Translate(trans) { // 这里报错
errs = append(errs, &ValidError{
Key: key,
Message: value,
})
}
修改接口:zh,无参数,就出现(runtime error: invalid memory address or nil pointer dereference)这个情况;en,正常返回。。
我跟着博客写到这里 发现创建的钩子函数未生效,而更新和删除的钩子函数生效了,请问下这有可能是什么原因 。。。 db.Callback().Create().Replace("gorm:update_timestamp", updateTimeStampForCreateCallback) 。。。 func updateTimeStampForCreateCallback(scope *gorm.Scope) { if !scope.HasError() { fmt.Printf("scope has no error") nowTime := time.Now().Unix() if createTimeField, ok := scope.FieldByName("CreatedOn"); ok { if createTimeField.IsBlank { = createTimeField.Set(nowTime) } }
if modifyTimeField, ok := scope.FieldByName("ModifiedOn"); ok { if modifyTimeField.IsBlank { _ = modifyTimeField.Set(nowTime) } } }
}
@GarfieldZhan 有完整代码吗,也有可能是已经走进你的插件逻辑里了,但没有走到具体的实现逻辑里去。如果是没走的话,得 debug 看看,看看是什么地方写错了没有走进去?
修改接口:zh,无参数,就出现(runtime error: invalid memory address or nil pointer dereference)这个情况;en,正常返回。。
@fjjreal 能具体描述一下不...只言片语,没法直接定位到你的具体意思。
在调用修改标签的接口时,state传0,会报入参错误。传1,就没事,请问是啥原因
type UpdateTagRequest struct {
ID uint32 form:"id" binding:"required,gte=1"
Name string form:"name" binding:"min=3,max=100"
State uint8 form:"state" binding:"required,oneof=0 1"
ModifiedBy string form:"modified_by" binding:"required,min=3,max=100"
}
楼上的把参数验证,required去掉就行了。@xiaoshiniudao6
问个可能显得很傻的问题。 为什么对数据库的操作代码是在model层,而不是dao层呀?
var err error
if pageOffset >= 0 && pageSize > 0 {
db = db.Offset(pageOffset).Limit(pageSize)
}
if t.Name != "" {
db = db.Where("name = ?", t.Name)
}
db = db.Where("state = ?", t.State)
if err = db.Where("is_del = ?", 0).Find(&tags).Error; err != nil {
return nil, err
}
代码中的db变量会被改变吗?比如我第二次搜索,会不会在上次搜索的结果中搜索?
调用修改接口state设置0不成功
解决方案:binding:"required"
会认为0是空值而不通过校验
把整数字段改成整数指针类型,指针没有默认值0,也就没有这个问题了,注意取值加*,设值加&总之记得他是指针就好了
实测ok
在修改标签过程中 输入
curl -X PUT http://127.0.0.1:8000/api/v1/tags/{1} -F state=0 -F modified_by=eddycjy
结果
{"code":10000001,"details":["ID is a required field","Name must be at least 1 character in length"],"msg":"Invalid Args"}%
但是在UpdateTagRequest里,我没有限制Name为requreid
type UpdateTagRequest struct {
ID uint32 `form:"id" binding:"required,gte=1"`
Name string `form:"name" binding:"min=1,max=100"`
State uint8 `form:"state" binding:"oneof=0 1"`
ModifiedBy string `form:"modified_by" binding:"required,min=3,max=100"`
}
如果补上name参数,可以正常修改,例如输入命令
curl -X PUT http://127.0.0.1:8000/api/v1/tags/{1} -F 'name=Go' -F state=0 -F modified_by=eddycjy
github.com/gin-gonic/gin v1.7.7
github.com/go-playground/validator/v10 v10.9.0
包版本, updateTag, state=0
时会提示 State为必填字段
错误,解决办法按楼上 YingYou 方法使用指针可完美解决。不知道这样会不会有性能问题
type UpdatedTagRequest struct {
Id uint32 `form:"id" binding:"required,gte=1"`
Name string `form:"name" binding:"min=3,max=100"`
State *uint8 `form:"state" binding:"required,oneof=0 1"`
ModifiedBy string `form:"modified_by" binding:"required,min=3,max=100"`
}
@Zrealshadow 那位老哥 我也是遇到name校验的同样问题 请问不加require为什么还是必须校验啊
$ curl -X POST http://127.0.0.1:8000/api/v1/tags -F 'name=Go' -F created_by=eddycjy 验证新增标签接口这里,name参数不能加引号,否则验证不通过。
@fjjreal 的问题我也遇到了,应该是个 bug
locale := c.GetHeader("locale") trans, _ := uni.GetTranslator(locale)
这一行如果 header 中没有 locale 就拿不到 translator,我改成
if locale == "" { locale = "zh" }
就不会报错了,总之要考虑拿不到 translator 的情况
@Zrealshadow,没写required但是写了min,所以,把min改为min=0就可以了
问个可能显得很傻的问题。 为什么对数据库的操作代码是在model层,而不是dao层呀?
我也想问同样的这个问题,为什么要多个model
github.com/gin-gonic/gin v1.7.7 github.com/go-playground/validator/v10 v10.9.0
包版本, updateTag,
state=0
时会提示State为必填字段
错误,解决办法按楼上 YingYou 方法使用指针可完美解决。不知道这样会不会有性能问题type UpdatedTagRequest struct { Id uint32 `form:"id" binding:"required,gte=1"` Name string `form:"name" binding:"min=3,max=100"` State *uint8 `form:"state" binding:"required,oneof=0 1"` ModifiedBy string `form:"modified_by" binding:"required,min=3,max=100"` }
我在这里给State指针赋值,有没有其他好方法
func (t Tag) Update(c *gin.Context) {
newstate := convert.StrTo(c.Param("state")).MustUInt8()
param := service.UpdateTagRequest{
ID: convert.StrTo(c.Param("id")).MustUInt32(),
State: &newstate,
}
gorm v2版本没有gorm解决方案
func (m *Model) BeforeUpdate(tx *gorm.DB) error {
now := time.Now().Unix()
tx.Statement.SetColumn("modified_at", now)
return nil
}
每次都要 svc := service.New(c.Request.Context()) 很烦啊
修改标签接口 curl -X PUT http://127.0.0.1:8000/api/v1/tags/{id} -F state=0 -F modified_by=eddycjy 提示id为必填字段,name长度必须至少为3个字符,与文章返回结果不符 原因: shouldBind绑定不了路径参数,应该要用ShouldBindUri name有min=3,max=100,没有传name时也会检测
@EricWangZ 我没有加把传参转换成int的步骤也成功了,不知道是不是gin的ShouldBind有把int智能的转换成int的功能? 求解
@YingYou 我只改了UpdateTagRequest成功了 没管请求参数,不知道是不是gin的ShouldBind有把int智能的转换成*int的功能? 求解
大家好 我在执行
curl -X GET 'http://127.0.0.1:8000/api/v1/tags?page=2&page_size=2'
{"list[{"id":3,"created_by":"eddycjy","modified_by":"","created_on":1662619240,"modified_on":1662619240,"deleted_on":0,"is_del":0,"name":"Rust","state":1}],"pager":{"page":2,"page_size":2,"total_rows":3}}
这一操作后报错{"code":20010001,"msg":"获取标签列表失败"}zsh: command not found: list:[id:3],pager:page:2 zsh: command not found: list:[id:3],pager:page:2
想询问一下大家这个报错出现的原因是什么
@fjjreal 遇到了同样的问题 你有解决吗?
有没有同学遇到这个参数校验的问题? curl -X GET 'http://127.0.0.1:8000/api/v1/tags?state=6
runtime error: invalid memory address or nil pointer dereference /usr/local/Cellar/go@1.18/1.18.7/libexec/src/runtime/panic.go:220 (0x1049e86) panicmem: panic(memoryError) /usr/local/Cellar/go@1.18/1.18.7/libexec/src/runtime/signal_unix.go:818 (0x1049e56) sigpanic: panicmem() /Users/admin/project/blog-service/pkg/logger/logger.go:111 (0x13499c6) (Logger).JSONFormat: data["callers"] = l.callers /Users/admin/project/blog-service/pkg/logger/logger.go:126 (0x1349c1c) (Logger).Output: fmt.Print(l.JSONFormat(level, message)) /Users/admin/project/blog-service/pkg/logger/logger.go:167 (0x1349fcb) (Logger).Errorf: l.Output(LevelError, fmt.Sprintf(format, v...)) /Users/admin/project/blog-service/internal/routers/api/v1/tag.go:35 (0x1613dea) Tag.List: global.Logger.Errorf("app.BindAndValid errs: %v", errs) /Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x1546801) (Context).Next: c.handlersc.index /Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/recovery.go:101 (0x15467ec) CustomRecoveryWithWriter.func1: c.Next() /Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x15458e6) (Context).Next: c.handlersc.index /Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/logger.go:240 (0x15458c9) LoggerWithConfig.func1: c.Next() /Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/context.go:173 (0x15449b0) (Context).Next: c.handlersc.index /Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:616 (0x1544618) (Engine).handleHTTPRequest: c.Next() /Users/admin/go/pkg/mod/github.com/gin-gonic/gin@v1.8.1/gin.go:572 (0x154415c) (Engine).ServeHTTP: engine.handleHTTPRequest(c) /usr/local/Cellar/go@1.18/1.18.7/libexec/src/net/http/server.go:2916 (0x12a2eda) serverHandler.ServeHTTP: handler.ServeHTTP(rw, req) /usr/local/Cellar/go@1.18/1.18.7/libexec/src/net/http/server.go:1966 (0x129ded6) (*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req) /usr/local/Cellar/go@1.18/1.18.7/libexec/src/runtime/asm_amd64.s:1571 (0x1064880) goexit: BYTE $0x90 // NOP
我发现 curl -X POST http://127.0.0.1:8000/api/v1/tags -F 'name=Go' -F created_by=eddycjy2 请求会报 {"code":10000001,"msg":"入参错误"} 使用 则可以插入新数据成功,不知道为啥 curl --location --request POST 'http://127.0.0.1:8000/api/v1/tags' \ --form 'name="Go"' \ --form 'created_by="eddycjy2233"'
上一个问题,是我的问题
CreateTagRequest 结构体中Name string form:"name" binding:"required,min=2,max=100"
最小值我写成了min=3,所以一直校验不通过,name最小字符数改为2就可以通过
为什么要用"created_on","modified_on", "deleted_on"这些字段?而不用“created_at", "updated_at", "deleted_at"?这样当数据变化时,gorm可以自动更新相关字段
为什么感觉用go开发个项目这么复杂呢, 是因为教程里没有用到现有的包进行简化吗? 如果都是这样手撸代码 开发个正式项目可真的要累坏了 我以为java够重、配置够繁琐了,学完这节课,发现go也没好哪儿去,一层套一层,给人都弄晕了
service/tag.go 为什么写到这里会报错 func (svc Service) CountTag(param CountTagRequest) (int, error) { return svc.dao.CountTag(param.Name, param.State) ----这段提示有问题 }
模块开发:标签管理 | Go 语言编程之旅
2.6 模块开发:标签管理 在初步完成了业务接口的入参校验的逻辑处理后,接下来我们正式的进入业务模块的业务逻辑开发,在本章节将完成标签模块的接口代码编写,涉及的接口如下: 功能 HTTP 方法 路径 新增标签 POST /tags 删除指定标签 DELETE /tags/:id 更新指定标签 PUT /tags/:id 获取标签列表 GET /tags 2.6.1 新建 model 方法 首先我们
https://golang2.eddycjy.com/posts/ch2/06-api-tag-module/