Skip to main content
Version: 2.8.x(Latest)

Introduction

You may have noticed that when we specify a struct, our rules can only validate its key-values or attributes. If we want to use the rules to completely validate the struct object, we find that we cannot register custom validation rules for the validation component. However, our validation component also supports directly validating the current struct object. Let's look at an example where we need to perform complete custom validation on a user creation request and register a validation rule for UserCreateReq to achieve this.

Usage Example

package main

import (
"context"
"fmt"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/v2/util/gvalid"
"time"
)

type UserCreateReq struct {
g.Meta `v:"UserCreateReq"`
Name string
Pass string
}

func RuleUserCreateReq(ctx context.Context, in gvalid.RuleFuncInput) error {
var req *UserCreateReq
if err := in.Data.Scan(&req); err != nil {
return gerror.Wrap(err, `Scan data to UserCreateReq failed`)
}
// SELECT COUNT(*) FROM `user` WHERE `name` = xxx
count, err := g.Model("user").Ctx(ctx).Cache(gdb.CacheOption{
Duration: time.Hour,
Name: "",
Force: false,
}).Where("name", req.Name).Count()
if err != nil {
return err
}
if count > 0 {
return gerror.Newf(`The name "%s" is already taken by others`, req.Name)
}
return nil
}

func main() {
var (
ctx = gctx.New()
user = &UserCreateReq{
Name: "john",
Pass: "123456",
}
)
err := g.Validator().RuleFunc("UserCreateReq", RuleUserCreateReq).Data(user).Run(ctx)
fmt.Println(err)
}

As you can see, by embedding g.Meta metadata into the struct and binding the custom rule UserCreateReq, when we validate the struct object through CheckStruct, we can use UserCreateReq to achieve validation.

After executing the above example, the terminal output:

The name "john" is already taken