views:

380

answers:

1

I have a composite domain object as follows:

class Person 
{
    static embedded = ['forSale']
    Boolean isSelling
    House forSale
}

class House 
{
    Integer numBedrooms
}

I have a select control for the numBedrooms as follows:

<tr class="prop">
 <td valign="top" class="name">
   <label for="numBedrooms"><g:message code="person.numBedrooms.label" default="Num Bedrooms" /></label>
 </td>
 <td valign="top" class="value ${hasErrors(bean: personInstance, field: 'forSale.numBedrooms', 'errors')}">
     <g:select name="numBedrooms" value="${fieldValue(bean: personInstance, field: 'forSale.numBedrooms')}" 
          noSelection="${['null':'Select a number...']}"
      from="${1..6}"
     />
 </td>
</tr>

Notice that I am using forSale.numBedrooms in the fieldValue on the select. I haven't been able to produce scaffolded code for this to take a look at how it is supposed to be done because the create view which gets generated by create-views contains no references to the fields in the forSale House object.

I also haven't been able to turn up any exampes of composite fields being accessed via GSP, so this is a bit of a guess. In any case the GSP page renders without errors, although that may be because I haven't been able to save any data.

I send the value of numBedrooms back as part of a URl query string...

&numBedrooms=2

When I do this the save code in my controller is failing silently - at least nothing ever gets written to the database. I have switched on debug logging for pretty much everything but I get no messages in the log which suggest anything is wrong, although something obviously is.

If I remove the numBedrooms parameter from the query string then my save proceeds as normal, so I am guessing it is something to do with resolving numBedrooms.

Any clue what I am doing wrong and what I can do to track down my problem?

A: 

What I do is generate-all for the House Domain then copy and paste the GSP code and remove the files once I am done. I have also found it smarter to create templates to edit the House domain in the case where I am using the House domain later on.

For you GSP you need something like this (Notice the name attribute)

<tr class="prop">
 <td valign="top" class="name">
   <label for="forSale.numBedrooms"><g:message code="house.numBedrooms.label" default="Num Bedrooms" /></label>
 </td>
 <td valign="top" class="value ${hasErrors(bean: personInstance.forSale, field: 'numBedrooms', 'errors')}">
     <g:select name="forSale.numBedrooms" value="${fieldValue(bean: personInstance.forSale, field: 'numBedrooms')}" 
          noSelection="${['null':'Select a number...']}"
      from="${1..6}"
     />
 </td>
</tr>

In your param string you need *forSale*.numBedrooms=2. this code will work with person.properties = params or new Person(params).

The embedded "instruction" only tells Hibernate to include the parameters in the same table they are still seperate Domain classes. It will probably generate a table for the domain even though you may never use it.

Hope this helps.

Scott Warren
If you check my code you'll see I am using forSale.numBedrooms and I changed the url parameter to refer to it too. When I check what is coming through on the URL parameters I get my forSale fields grouped together into an object. What's more I assign using the params assignment to properties as you suggest. The trouble is that my table rows don't get updated. Something in the stack, be it grails or hibernate, is failing silently. I have debug logging switched on for everything and a 128Mb log file and no messages saying the update failed. I have no clue what's happening.
Simon
Your code has <g:select name="numBedrooms".. /> you need code like <g:select name="forSale.numBedrooms".. />
Scott Warren