Question

I have three objects.

class Registrant {
  String firstName
  String lastName

  List<EventRegistration> events = [].withLazyDefault { new EventRegistration() }

  static hasMany = [
    events: EventRegistration
  ]
}

class EventRegistration {
  static belongsTo = [ registrant : Registrant ]
  Event event
  Integer numberOfTickets
}

class Event {
  String title
}

Events are hydrated to the form from the database.

A registrant should be able to register for events with the number of tickets they wish to receive. I'd set up my form like this:

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th># of Tickets</th>
    </tr>
  </thead>
  <tbody>
    <g:each var="event" in="${Event.list()}" status="s">
    <tr>
      <td>${event.title}</td>
      <td><g:field type="text" name="registrant.events[${s}].numberOfTickets"/>
      <g:field type="hidden" name="registrant.events[${s}].event.id" value="${event?.id}"/></td>
    </tr>
    </g:each>
  </tbody>
</table>

Controller Code:

@Transactional(readOnly = true)
class RegistrantController {

  def index() {  
  }

  def load(Registrant registrant){
    render(view: "load", model:[registrant:registrant])
  }

  @Transactional
  def save(Registrant registrant) { 

    println registrant?.events

    if (registrant == null){
      flash.message = "registrant.save.not.found"
      render view:'index'
      return
    }

    if (registrant.hasErrors()) {
      flash.message = "registrant.save.errors"
      render view:'index', model:[registrant:registrant]
      return
    }

    if (registrant.save(flush:true)) {
      redirect action: "load", id:registrant.id 
    }
    else {
      flash.message = "registrant.save.errors"
      render view:'index', model:[registrant:registrant]
      return
    }
  } 
}

This doesn't save. Is there a way to associate the Event to the EventRegistration so Registrant can save it?

Was it helpful?

Solution

Since the scope of your binding in your controller is the registrant you don't need to prefix the events elements with registrant. Remove that from your tags and binding will work.

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th># of Tickets</th>
    </tr>
  </thead>
  <tbody>
    <g:each var="event" in="${Event.list()}" status="s">
    <tr>
      <td>${event.title}</td>
      <td><g:field type="text" name="events[${s}].numberOfTickets"/>
      <g:field type="hidden" name="events[${s}].event.id" value="${event?.id}"/></td>
    </tr>
    </g:each>
  </tbody>
</table>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top