Crusaderpyro
Crusaderpyro

Reputation: 2242

How to perform conditional required validation ussing ozzo validation in golang?

In Golang ozzo-validation, how can I validate a field which is dependent on another field ?

For example, if I have the following:

return validation.ValidateStruct(&c,
      validation.Field(&c.Name, validation.Required, validation.Length(5, 20)),

      validation.Field(&c.Gender, validation.In("Female", "Male")),

      validation.Field(&c.Email, is.Email),

      validation.Field(&c.Address),

How can I add a validation that the Address is required only if email is not empty?

Upvotes: 0

Views: 5415

Answers (2)

Nestor
Nestor

Reputation: 747

The library now supports conditional validation by the validation.When function.

Here is a code snipped which fits the validation you described.

package main

import (
        "fmt"

        validation "github.com/go-ozzo/ozzo-validation" // or "github.com/go-ozzo/ozzo-validation/v4" if "When" not found
)

type Entry struct {
        Name    string
        Gender  string
        Email   string
        Address string
}

func main() {
        v := func(e Entry) {
                fmt.Println(validation.ValidateStruct(&e,
                        validation.Field(&e.Name, validation.Required, validation.Length(5, 20)),

                        // Note that if gender is "" and not required, validation returns no error.
                        validation.Field(&e.Gender, validation.Required, validation.In("Female", "Male")),

                        validation.Field(&e.Address, validation.When(e.Email != "", validation.Required.Error("Address is required if Email is set"))),
                ))
        }

        // All is fine for no Email.
        e := Entry{
                Name:   "My name is!",
                Gender: "Male",
        }
        v(e)

        // Validation fails for Email and no Address.
        e = Entry{
                Name:   "My name is!",
                Gender: "Male",
                Email:  "[email protected]",
        }
        v(e)
}

It outputs.

<nil>
Address: Address is required if Email is set.

The library documentation describes it as well: https://github.com/go-ozzo/ozzo-validation#conditional-validation

Upvotes: 4

jeevatkm
jeevatkm

Reputation: 4791

You can achieve it in two ways-

  • Adding your own custom rules
  • Conditionally add FieldRules based on precondition-value i.e check Email while creating field rules then supply it to validation.ValidateStruct

For e.g.:

type Sample struct {
    Name    string
    Gender  string
    Email   string
    Address Address
}

type Address struct {
    // ... fields
}

func (s Sample) Validate() error {
    var fieldRules []*validation.FieldRules

    fieldRules = append(fieldRules, validation.Field(&s.Name, validation.Required, validation.Length(5, 20)))
    fieldRules = append(fieldRules, validation.Field(&s.Gender, validation.In("Female", "Male")))
    fieldRules = append(fieldRules, validation.Field(&s.Email, is.Email))

    if len(strings.TrimSpace(s.Email)) > 0 {
        fieldRules = append(fieldRules, validation.Field(&s.Address, validation.Required))
        fieldRules = append(fieldRules, validation.Field(&s.Address))
    }

    return validation.ValidateStruct(&s, fieldRules...)
}

Upvotes: 5

Related Questions