The Homepage of Daniel Hollands: Web Development Graduate!
28 Oct 2009
I’ve been able to fix this problem, check out my solution.
I’m looking for some help getting Cake to save data to three different models all from one form. The three models in question are Story, Chapter and Path, each of which looks like this:
CREATE TABLE IF NOT EXISTS `stories` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `slug` varchar(30) COLLATE utf8_unicode_ci NOT NULL, `title` varchar(30) COLLATE utf8_unicode_ci NOT NULL, `introduction` text COLLATE utf8_unicode_ci NOT NULL, `background` text COLLATE utf8_unicode_ci NOT NULL, `approved` tinyint(1) NOT NULL, `created` datetime DEFAULT NULL, `modified` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) CREATE TABLE IF NOT EXISTS `chapters` ( `id` int(11) NOT NULL AUTO_INCREMENT, `story_id` int(11) NOT NULL, `user_id` int(11) NOT NULL, `path_id` int(11) NOT NULL, `title` varchar(30) COLLATE utf8_unicode_ci NOT NULL, `content` text COLLATE utf8_unicode_ci NOT NULL, `approved` tinyint(1) NOT NULL, `views` int(11) NOT NULL, `created` datetime DEFAULT NULL, `modified` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) CREATE TABLE IF NOT EXISTS `paths` ( `id` int(11) NOT NULL AUTO_INCREMENT, `chapter_id` int(11) NOT NULL, `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `created` datetime DEFAULT NULL, `modified` datetime DEFAULT NULL, PRIMARY KEY (`id`) )
With the following relations:
I also have $recursive set to -1 across the whole site as I’m using the Containable Behaviour.
The idea is that upon adding a story to the site, you also need to provide the first chapter of the story, and then two paths which lead away from the chapter.
The code for the form is:
<?php echo $form->create('Story', array('url' => '/stories/add/'));?>
<fieldset>
<legend>Story information</legend>
<dl>
<dt><?php echo $form->label('Story.title', 'Story title'); ?></dt>
<dd><?php echo $form->text('Story.title'); ?></dd>
<dd><?php echo $form->error('Story.title'); ?></dd>
<dt><?php echo $form->label('Story.introduction', 'Story introduction'); ?></dt>
<dd><?php echo $form->textarea('Story.introduction'); ?></dd>
<dd><?php echo $form->error('Story.introduction'); ?></dd>
<dt><?php echo $form->label('Story.background', 'Story background'); ?></dt>
<dd><?php echo $form->textarea('Story.background'); ?></dd>
<dd><?php echo $form->error('Story.background'); ?></dd>
</dl>
</fieldset>
<fieldset>
<legend>First chapter</legend>
<dl>
<dt><?php echo $form->label('Chapter.title', 'Chapter title'); ?></dt>
<dd><?php echo $form->text('Chapter.title'); ?></dd>
<dd><?php echo $form->error('Chapter.title'); ?></dd>
<dt><?php echo $form->label('Chapter.content', 'Chapter content'); ?></dt>
<dd><?php echo $form->textarea('Chapter.content'); ?></dd>
<dd><?php echo $form->error('Chapter.content'); ?></dd>
<dt><?php echo $form->label('NextPath.0.title', 'First path'); ?></dt>
<dd><?php echo $form->text('NextPath.0.title'); ?></dd>
<dd><?php echo $form->error('NextPath.0.title'); ?></dd>
<dt><?php echo $form->label('NextPath.1.title', 'Second path'); ?></dt>
<dd><?php echo $form->text('NextPath.1.title'); ?></dd>
<dd><?php echo $form->error('NextPath.1.title'); ?></dd>
</dl>
</fieldset>
<?php echo $form->end('Submit');?>
And the code for the controller is:
function add()
{
// check if form has been submitted
if (!empty($this->data)) // form not empty, continue
{
$this->data['Story']['user_id'] = $this->Auth->user('id');
$this->data['Chapter']['user_id'] = $this->Auth->user('id');
$this->data['Chapter']['path_id'] = 0; // set to zero because there is no previous path
// attempt to save data
if ($this->Story->saveAll($this->data, array('validate' => 'first'))) // passed validation and successfully saved
{
// set success message and forward to posted chapter
$this->Session->setFlash('The story has been saved', 'success');
$this->redirect(array('controller' => 'pages', 'action' => 'storyadded'));
}
else // chapter unable to save, set error message and return to form
{
$this->Session->setFlash('The story could not be saved. Please fix the errors below.', 'warning');
}
}
}
The problem I have is that when I submit an empty form, the validation for the Story and Chapter models works (displays the correct error messages next to the correct fields), but the ones for the Paths do not. I also get a couple of errors along the top of the page:
Warning (2): Cannot use a scalar value as an array [CORE\cake\libs\model\model.php, line 1590]
Warning (2): preg_match() expects parameter 2 to be string, array given [CORE\cake\libs\validation.php, line 848]
If I submit the form with valid data, the stories table populates correctly, the chapters table almost populates correctly (the story_id field is left blank, and the first characters of the title and content fields is replaced with the value that should be in story_id), but the paths do not populate at all.
I really hope that someone out there on the internets can help me with this problem. Thank you