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

[Question] How do I validate slice of struct inside a struct? #235

Open
budimanjojo opened this issue Sep 15, 2023 · 0 comments
Open

[Question] How do I validate slice of struct inside a struct? #235

budimanjojo opened this issue Sep 15, 2023 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@budimanjojo
Copy link

budimanjojo commented Sep 15, 2023

System (please complete the following information):

  • OS: linux
  • GO Version: 1.21
  • Pkg Version: 1.5.1

Describe the bug

A clear and concise description of what the bug is.

To Reproduce

package main

import (
        "fmt"

        "github.com/gookit/validate"
)

type Config struct {
        Nodes []Node
}

type Node struct {
        Name string `validate:"required_with:Nodes..Location"`
        Location string
}

func main() {
        data := &Config{
                Nodes: []Node{
                        {
                                Name: "node1"
                                Location: "A",
                        },
                        {
                        },
                },
        }

        v := validate.Struct(data)
        v.StopOnError = false
        if v.Validate() {
                fmt.Println("Good config")
        } else {
                fmt.Println(v.Errors)
        }
}

The above resulted in:

Nodes.1.Name:
 required_with: Nodes.1.Name field is required when [Nodes.Location] is present

I have tried with required_without and required_unless. I also tried using Nodes.Location as the field too and nothing works.

Expected behavior

Nodes.1.Name shouldn't fail because it doesn't have Location field set.

Screenshots

If applicable, add screenshots to help explain your problem.

Additional context

I can actually fix this by having a custom validator on the Nodes like this:

package main

import (
        "fmt"

        "github.com/gookit/validate"
)

type Config struct {
        Nodes []Node `validate:"customFunction"`
}

type Node struct {
        Name string
        Location string
}

func (c Config) CustomFunction(nodes []Node) bool {
        for k := range nodes {
                if nodes[k].Location != "" && nodes[k].Name == "" {
                        return false
                }
        }
        return true
}

func (c Config) Messages() map[string]string {
        return validate.MS{
                "customFunction": "each {field} needs `Name` set if `Location` is set",
        }
}

But I maybe there's a better way to do this? Or at least I can return the field on c.CustomFunction() so I can have a nice output like this: Nodes.1.Name is required if Nodes.1.Location is not empty.

@inhere inhere added the enhancement New feature or request label Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants