0

I try to validate a nested domain class instance on a command object.

Having the following command object

package demo

import grails.databinding.BindingFormat

class SaveEventCommand {

    @BindingFormat('yyyy-MM-dd')
    Date date

    Refreshment refreshment

    static constraints = {
        date validator: { date -> date > new Date() + 3}
        refreshment nullable: true
    }
}

And having the following domain class with its own constraints

package demo

class Refreshment {

    String food
    String drink
    Integer quantity

    static constraints = {
        food inList: ['food1', 'food2', 'food3']
        drink nullable: true, inList: ['drink1', 'drink2', 'drink3']
        quantity: min: 1
    }
}

I need when refreshment is not nullable the command object validates the date property and check the corresponding restrictions in refreshment instance

For now try with this code in the controller:

def save(SaveEventCommand command) {
    if (command.hasErrors() || !command.refreshment.validate()) {
        respond ([errors: command.errors], view: 'create')

        return
    }

    // Store logic goes here
}

Here through !command.refreshment.validate() I try to validate the refresh instance but I get the result that there are no errors, even when passing data that is not correct.

Thank you any guide and thank you for your time

1
  • command.validated(); command.refreshment.validate(); if (command.hasErrors() || command.refreshment.hasErrors()) { println "hit this block"; respond ([errors: command.errors?:command?.refreshment?.errors], view: 'create') you could try somethign like this add some verbosity to see if it hits block i also altered it so it validates first then trys to check if it has errors Commented Oct 24, 2017 at 16:32

2 Answers 2

1

I typically just include some code that will use a custom validator to kick off validation for any property that is composed of another command object. For example:

thePropertyInQuestion(nullable: true, validator: {val, obj, err ->
    if (val == null) return
    if (!val.validate()) {
        val.errors.allErrors.each { e ->
            err.rejectValue(
                "thePropertyInQuestion.${e.arguments[0]}",
                "${e.objectName}.${e.arguments[0]}.${e.code}",
                e.arguments,
                "${e.objectName}.${e.arguments[0]}.${e.code}"
            )
        }
    }
})

This way it's pretty clear that I want validation to occur. Plus it moves all the errors up into the root errors collection which makes things super easy for me.

Sign up to request clarification or add additional context in comments.

2 Comments

Hello and thanks for replying, I checked your solution and it works as expected so the question is certainly answered, but now I have a problem with the condition that val (following your example) can be null. The condition if (val == null) return is not fulfilled because as inspected the value of val is an instance of Refreshment marked as demo.Refreshment : (unsaved) with the following properties [food:null, drink:null, event:null, quantity:null, eventId:null]
In order to make it work instead of if (val == null) return true i am using if (!val.food && !val.quantity) return true here I evaluate the properties food and quantity because they are in the domain class refreshments required. Any idea for a groovier solution!
0

Two things I could think of:

  1. Implement grails.validation.Validateable on your command object
  2. What happens when you provide an invalid date? Can you see errors while validating?

1 Comment

The command object is defined in the controller class so is marked as validetable and about the date yes if i provide an invalid date i get an error message.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.