-
Notifications
You must be signed in to change notification settings - Fork 43
/
callbacks.go
79 lines (71 loc) · 2.51 KB
/
callbacks.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package validations
import (
"fmt"
"regexp"
"strings"
"github.com/asaskevich/govalidator"
"github.com/jinzhu/gorm"
)
var skipValidations = "validations:skip_validations"
func validate(scope *gorm.Scope) {
if _, ok := scope.Get("gorm:update_column"); !ok {
if result, ok := scope.DB().Get(skipValidations); !(ok && result.(bool)) {
if !scope.HasError() {
scope.CallMethod("Validate")
if scope.Value != nil {
resource := scope.IndirectValue().Interface()
_, validatorErrors := govalidator.ValidateStruct(resource)
if validatorErrors != nil {
if errors, ok := validatorErrors.(govalidator.Errors); ok {
for _, err := range flatValidatorErrors(errors) {
scope.DB().AddError(formattedError(err, resource))
}
} else {
scope.DB().AddError(validatorErrors)
}
}
}
}
}
}
}
func flatValidatorErrors(validatorErrors govalidator.Errors) []govalidator.Error {
resultErrors := []govalidator.Error{}
for _, validatorError := range validatorErrors.Errors() {
if errors, ok := validatorError.(govalidator.Errors); ok {
for _, e := range errors {
resultErrors = append(resultErrors, e.(govalidator.Error))
}
}
if e, ok := validatorError.(govalidator.Error); ok {
resultErrors = append(resultErrors, e)
}
}
return resultErrors
}
func formattedError(err govalidator.Error, resource interface{}) error {
message := err.Error()
attrName := err.Name
if strings.Index(message, "non zero value required") >= 0 {
message = fmt.Sprintf("%v can't be blank", attrName)
} else if strings.Index(message, "as length") >= 0 {
reg, _ := regexp.Compile(`\(([0-9]+)\|([0-9]+)\)`)
submatch := reg.FindSubmatch([]byte(err.Error()))
message = fmt.Sprintf("%v is the wrong length (should be %v~%v characters)", attrName, string(submatch[1]), string(submatch[2]))
} else if strings.Index(message, "as numeric") >= 0 {
message = fmt.Sprintf("%v is not a number", attrName)
} else if strings.Index(message, "as email") >= 0 {
message = fmt.Sprintf("%v is not a valid email address", attrName)
}
return NewError(resource, attrName, message)
}
// RegisterCallbacks register callback into GORM DB
func RegisterCallbacks(db *gorm.DB) {
callback := db.Callback()
if callback.Create().Get("validations:validate") == nil {
callback.Create().Before("gorm:before_create").Register("validations:validate", validate)
}
if callback.Update().Get("validations:validate") == nil {
callback.Update().Before("gorm:before_update").Register("validations:validate", validate)
}
}