Saturday, November 28, 2015

Displaying, validating and saving multiple models in a form

Hi,

I'm working on an event management system for a small educational company, that's turned out to be more complex than expected (isn't that always the way?).

Basically, people apply online to book their child/children on a course instance. They initially state how many child places they want to book, then the form generates the appropriate number of field sets for the number of children, creating them using a count and naming the fields 'Kids.X.fieldname' based on that count.

The form is multi-model - saving the booking details, the parents details and the child details separately. A 'User' account is created from the parents details, 'Kids' are owned by 'Users' and I've set it up so that 'Bookings' are owned by 'Users' (and the course 'Instances' they are related to) but also have a HABTM relationship with 'Kids'. I've done it like this so that in Users can add individual kids to any future bookings (they have a lot of people coming back for more).

It seems to (mostly) work okay for when one child is selected - it validates the data entered against the appropriate model, including the 'Kid', processes the form and writes the data to the respective tables - the only glitch being it doesn't seem to create the 'Kid' though does add a phantom 'kid_id' to the 'bookings_kids' table!

However, it works even less well for when there are multiple kids. It processes the form but doesn't validate the multiple 'Kids' fields (even though the form is still indicating that they are required by putting labels in bold etc) and doesn't create the 'Kids' data or the add the relationship to 'bookings_kids'.

Any idea what I may be doing wrong? I've been tempted to give up and just 'hardcoding' the children as part of the User table, but that limits the number and makes it less elegantly Cakey.

Here's the pertinent code I am using:

Models (have removed validation code etc for brevity)

class Instance extends AppModel {
public $belongsTo = array('Course');
public $hasMany = array('Booking');

}


class User extends AppModel {
public $hasMany = array('Booking','Kid');

}


class Kid extends AppModel {

public $belongsTo = array('User');
public $hasAndBelongsToMany = ('Booking');

}


class Booking extends AppModel {

public $belongsTo = array('Instance','User');
public $hasAndBelongsToMany = ('Kid');

}


InstanceController (am using this to process everything - all relevant models declared in $uses)

public function book($instanceID) 
    {

<--- CODE FOR CHECKING STUFF AND CREATING VARIABLES ETC-->
if ($this->request->is('post') and $status =='Confirmed') 
{
            $this->Booking->create();
            if ($this->Booking->saveAll($this->request->data)) 
            {
                $this->Session->setFlash(__('Your booking has been made. Thank you!'));
                return $this->redirect(array('controller'=>'instances','action' => 'view',$instanceID));
            }
            $this->Session->setFlash(__('There was an error - please check you have completed the form.'));
        }
    }



View (book.cp - edited for brevity)

echo $this->Form->create('Booking');
echo '<h3>Your Details</h3>';
echo $this->Form->input('User.firstname', array('label' => 'First name'));
echo $this->Form->input('User.surname', array('label' => 'Surname'));
echo $this->Form->input('User.username', array('label' => 'Email Address'));
echo $this->Form->input('User.phone', array('label' => 'Phone (mobile preferred)'));
if ($children == 1) {
echo "<h3>Your child's details</h3>";
echo $this->Form->input('Kid.name', array('label' => 'Child\'s Name'));
echo $this->Form->input('Kid.age', array('label' => 'Child\'s Age'));
} else {
echo "<h3>Your children's details</h3>";
$count = 1;
while ($count <= $children)
{
echo "<h4>Child " . $count . "</h4>";
echo $this->Form->input('Kid.'.$count.'.name', array('label' => 'Child\'s Name'));
echo $this->Form->input('Kid.'.$count.'.age', array('label' => 'Child\'s Age'));
echo "<hr>";
$count += 1;
}
}
echo $this->Form->end('Submit Booking'); 


Many thanks for looking!

--
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+unsubscribe@googlegroups.com.
To post to this group, send email to cake-php@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/d/optout.

No comments: