I have this controller which performs me a multiple domain databinding class, and it is working as i want. But i would like some help about the error messages. Is it possible to display error messages from multiple domain classes? If so, how should be the code both is the view and in the controller?

class CarroMovel {
    String move
    String rodas
    String espelhos
    Carro carro

    static hasMany = [carros: Carro]
    static belongsTo = Carro

    static constraints = {
        move(nullable:false, blank:false)
    }

    static mapping = {
        version false
    }
}

class Carro {

String name
String marca
String matricula

static constraints = {
    name(nullable:false, blank:false)
}

static mapping = {
    version false
}

}


def save3 = {

        def carroInstance = new Carro( )
        def carroMovelInstance = new CarroMovel( )

        carroInstance.name = params.carro.name
        carroInstance.marca = params.carro.marca
        carroInstance.matricula = params.carro.matricula

        carroMovelInstance.move = params.carroMovel.move
        carroMovelInstance.rodas = params.carroMovel.rodas
        carroMovelInstance.espelhos = params.carroMovel.espelhos

        carroInstance.save(failOnError: true)

        carroMovelInstance.carro = carroInstance
        carroMovelInstance.save(failOnError: true)

    }

<g:form controller="carro" action="save3">
<h1>Add New Carro Record</h1>
<p>Basic Information</p>

<label>Name
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.name" value="${carroInstance?.name}" /><br>

<label>Marca
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.marca" value="${carroInstance?.marca}" /><br

  <label>Matricula
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.matricula" value="${carroInstance?.matricula}" /><br>

<label>Move
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.move" value="${carroMovelInstance?.move}" /><br>

<label>Rodas
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.rodas" value="${carroMovelInstance?.rodas}" /><br>

<label>Espelho
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.espelhos" value="${carroMovelInstance?.espelho}" /><br>

<g:submitButton name="save" value="Save" id="addConference"/>


<div class="spacer"></div>
  </g:form>

                <g:hasErrors bean="${carroInstance}">
            <div class="errors">
                <g:renderErrors bean="${carroInstance}" as="list" />
            </div>
            </g:hasErrors>

Accepted Answer

Grails Validation Errors Primer

The errors for a domain object are stored in an errors property that is added to the object after it is validated. This property is an implementation of the Spring Errors interface.

You can get the errors either by calling the methods of this interface directly, e.g. to display the errors for the move field of a Carro instance:

List<FieldError> moveErrors = carroMovelInstance.errors?.getFieldErrors('move')   

To get the error messages for each error, you'll need a referrence to the messageSource bean created by Grails. You could get the message for each of the above errors with:

List<String> errorMessages = moveErrors.collect {error -> 
    messageSource.getMessage(error, Locale.default) 
}

Alternatively, Grails provides the eachError and renderErrors tags that simplify displaying errors and their corresponding messages in a GSP.


Specific Problems With Your Code

In your controller code, an exception will be thrown whenever save fails due to validation errors, so the view has no opportunity to display the errors. To fix this, change the controller so that it returns the domain objects (along with their errors) when saving fails

def save3 = {

    def carroInstance = new Carro( )
    def carroMovelInstance = new CarroMovel( )

    carroInstance.name = params.carro.name
    carroInstance.marca = params.carro.marca
    carroInstance.matricula = params.carro.matricula

    carroMovelInstance.move = params.carroMovel.move
    carroMovelInstance.rodas = params.carroMovel.rodas
    carroMovelInstance.espelhos = params.carroMovel.espelhos

    // I'm assuming in the code below that the view that displays the form is 'create.gsp'
    if (!carroInstance.save()) {
        render view: 'create', model : [carro: carroInstance, carroMovel: carroMovelInstance]
        return
    }

    carroMovelInstance.carro = carroInstance

    if (!carroMovelInstance.save()) {
        render view: 'create', model : [carro: carroInstance, carroMovel: carroMovelInstance]
    }

}

The GSP also needs to be changed to display these errors using either the Errors API directly or one of the Grails tags (see above)

Written by Don
This page was build to provide you fast access to the question and the direct accepted answer.
The content is written by members of the stackoverflow.com community.
It is licensed under cc-wiki