Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

requiredIf/requiredUnless doesn't work on bool field #683

Closed
bluven opened this issue Oct 28, 2020 · 7 comments · Fixed by #754
Closed

requiredIf/requiredUnless doesn't work on bool field #683

bluven opened this issue Oct 28, 2020 · 7 comments · Fixed by #754

Comments

@bluven
Copy link

bluven commented Oct 28, 2020

Package version eg. v9, v10:

v10

Issue, Question or Enhancement:

Issue

Code sample, to showcase or reproduce:

package main

import (
	"fmt"
	"github.com/go-playground/validator/v10"
)

type CreateRequest struct {
	Name        string     `json:"name" binding:"required,lte=50"`
	Description string     `json:"description" binding:"lte=2048"`
	AppID       uint       `json:"appID" binding:"required"`
	ForDeletion bool       `json:"forDeletion"`
	Delete      string
	Resources   []Resource `json:"resources" binding:"required_if=ForDeletion true"`
}

type Resource struct {
	Type    string `json:"type" binding:"required"`
	Content string `json:"content" binding:"required"`
	Name    string `json:"name" binding:"required,dns1123"`
}

func main() {
	validate := validator.New()
	validate.SetTagName("binding")

	req := CreateRequest{
		Name:        "test",
		AppID:       1,
		Delete:      "false",
		//Resources: []Resource{},
	}

	err := validate.Struct(req)
	if err == nil {
		fmt.Println("no error")
		return
	}

	if _, ok := err.(*validator.InvalidValidationError); ok {
		fmt.Println(err)
		return
	}

	for _, err := range err.(validator.ValidationErrors) {
		fmt.Println(err)
	}
}

I checked how requiredIf/requiredUnless is implemented, it seems this function doesn't has bool branch:

func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNotFoundValue bool) bool {
	field, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
	if !found {
		return defaultNotFoundValue
	}

	switch kind {

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return field.Int() == asInt(value)

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return field.Uint() == asUint(value)

	case reflect.Float32, reflect.Float64:
		return field.Float() == asFloat(value)

	case reflect.Slice, reflect.Map, reflect.Array:
		return int64(field.Len()) == asInt(value)
	}

	// default reflect.String:
	return field.return field.String() == value
}

I tried add a bool branch test like this and it worked:

func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNotFoundValue bool) bool {
	field, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
	if !found {
		return defaultNotFoundValue
	}

	switch kind {

	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return field.Int() == asInt(value)

	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return field.Uint() == asUint(value)

	case reflect.Float32, reflect.Float64:
		return field.Float() == asFloat(value)

	case reflect.Slice, reflect.Map, reflect.Array:
		return int64(field.Len()) == asInt(value)
	case reflect.Bool:
		return field.Bool() == asBool(value)
	}

	// default reflect.String:
	return field.String() == value
}

The last return feld.String() == value doesn't work on bool field, because the String() will return <bool Value>

@lixag
Copy link

lixag commented Jan 7, 2021

I found the same issue

@leefernandes
Copy link

@bluven did you open a PR with this?

@bluven
Copy link
Author

bluven commented Feb 5, 2021

@itsleeowen No. I didn't

@jpreese
Copy link

jpreese commented Feb 6, 2021

Looks to be the same problem with eqfield

	type Person struct {
		Name bool `validate:"eqfield=Age"`
		Age  bool
	}

	person := Person{
		Name: true,
		Age:  false,
	}

@nghialm269
Copy link

@bluven hi, could you open a PR with your changes so that this problem could be fixed?
@deankarn

@zane-deg
Copy link
Contributor

If this is blocking others like it was for me you can temporarily point your mod file at my fork (same commit sha as the PR above) by running the following:

go mod edit -replace github.com/go-playground/validator/v10=github.com/zane-deg/validator/v10@08356f8539dca47f241b5efdb0d1206bfab80014

@kaatinga
Copy link

kaatinga commented May 6, 2021

If this is blocking others like it was for me you can temporarily point your mod file at my fork (same commit sha as the PR above) by running the following:

go mod edit -replace github.com/go-playground/validator/v10=github.com/zane-deg/validator/v10@08356f8539dca47f241b5efdb0d1206bfab80014

Thank you for your work. Yesterday I was surprised that required_if did not work with boolean fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants