修正
バリデーション方法
フレームワーク「GIN」を使ってみた(CRUD処理) を改造して、バリデーションを追加します。
今回は、gopkg.in/go-playground/validator.v9 を利用します。
修正内容
以下のソースを追加します。
form/users.go
package forms
import (
"regexp"
"gopkg.in/go-playground/validator.v9"
)
type Users struct {
Id int
UserId string `validate:"required,min=5,max=25,alphanum"` // 必須、5~25文字、半角英数
Name string `validate:"required,is_tarou"` // 必須、カスタムバリデーション
}
// tarou はオリジナルバリデーション
func tarou(fl validator.FieldLevel) bool { //引数の型、返り値は固定
name := fl.Field().String()
tarou := regexp.MustCompile(`太郎`)
// name に太郎を含まないとエラーとする
return tarou.MatchString(name)
}
// バリデーションチェックを行って、結果とNGの場合にエラーメッセージ群を返す
func (form *Users) Validate() (ok bool, result map[string]string) {
result = make(map[string]string)
// 構造体のデータをタグで定義した検証方法でチェック
// err := validator.New().Struct(*form)
validate := validator.New()
validate.RegisterValidation("is_tarou", tarou) //第一引数をvalidateタグで設定した名前に合わせる
err := validate.Struct(*form)
if err != nil {
errors := err.(validator.ValidationErrors)
if len(errors) != 0 {
for i := range errors {
// フィールドごとに、検証
switch errors[i].StructField() {
case "UserId":
switch errors[i].Tag() {
case "required", "min", "max", "alphanum":
result["UserId"] = "5文字以上25文字以下の半角英数値で入力してください"
}
case "Name":
switch errors[i].Tag() {
case "required":
result["Name"] = "名前を入力してください"
case "is_tarou":
result["Name"] = "名前には、太郎を利用してください"
}
}
}
}
return false, result
}
return true, result
}
上記、バリデーションを登録処理のみ対応します。
修正箇所のみ記載します。
routes/users_controller.go
func Create(c *gin.Context) {
log.Print("登録処理")
DbConnection, _ := sql.Open("sqlite3", "./db/sqlite3/test.db") // main.goからのパスを指定
defer DbConnection.Close()
userid := c.PostForm("userID")
name := c.PostForm("name")
// 処理を追加
form := forms.Users{
UserId: userid,
Name: name,
}
log.Print("UserId : ", form.UserId)
log.Print("Name : ", form.Name)
// バリデーションの検証を行う
if ok, errorMessages := form.Validate(); !ok {
log.Print("入力エラーあり")
log.Print(errorMessages)
// ステータスコード:400を返す。(正しいかは分からない)
c.HTML(http.StatusBadRequest, "new", gin.H{"User": form, "errorMessages": errorMessages})
c.Abort()
}
// 処理を追加
cmd := "INSERT INTO m_users (user_id, name) VALUES (?, ?)"
_, err := DbConnection.Exec(cmd, userid, name)
if err != nil {
log.Fatalln(err)
}
c.Redirect(http.StatusMovedPermanently, "/user")
}
画面にもエラーメッセージの表示箇所を追加します。
templates/new.html
{{define "new"}}
<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="UTF-8">
<title>新規登録</title>
</head>
<body>
<form action="/user/new" method="POST">
user_id:<input type="text" name="userID" value="{{.User.UserId}}"> {{.errorMessages.UserId}}
<br>
name: <input type="text" name="name" value="{{.User.Name}}"> {{.errorMessages.Name}}
<br>
<input type="submit" value="登録">
</form>
</body>
</html>
{{end}}
参考サイト
go-playground/validator リクエストパラメータ向けValidationパターンまとめ
golang バリデート(validator.v9)
Golangでバリデーションチェックを行う
公式ドキュメント