I am building a CakePHP 2.3 application, and can't for the life of me figure out why saveAll keeps failing.
I have the following models:
ArtisthasManyArtistPreviewArtistPreviewbelongsToArtist
I have no problem saving my Artist model with the save() function, however as soon as I try to use the saveAll method, Cake seems to fail validation - which is crazy because I have even totally removed all my validation rules from my models.
Here's my view, nothing crazy:
<?php
echo $this->Form->create('Artist', array('inputDefaults' => array('class' => 'input-block-level')));
echo $this->Form->input('Artist.name', array('label' => __('Name')));
echo $this->Form->input('Artist.artist_section_id', array('label' => __('Section'), 'empty' => true));
?>
<label>Tags</label>
<div class="checkboxes">
<?php echo $this->Form->input('Tag', array('label' => false, 'multiple' => 'checkbox', 'class' => false));; ?>
</div>
<?php
echo $this->Form->input('Artist.website', array('label' => __('Website')));
echo $this->Form->input('ArtistPreview.0.url', array('label' => __('Artist Preview')));
echo $this->Form->input('Artist.description', array('label' => __('Description')));
?>
<?php
echo $this->Form->submit(__('Add'), array('class' => 'btn btn-primary btn-large', 'div' => false)) . ' ';
echo $this->Form->button(__('Cancel'), array('type' => 'button', 'class' => 'btn btn-large', 'div' => false, 'onclick' => 'closeDialog()'));
echo $this->Form->end();
?>
And here's my add controller method:
public function add() {
$this->layout = 'form';
if (!$this->request->is('ajax')) {
throw new ForbiddenException();
}
if ($this->request->is('post')) {
$this->setData($this->request->data['Artist'], array(
'user_id' => AuthComponent::user('id'),
'date' => $this->Date->gmt()
));
if ($this->Artist->saveAll($this->request->data)) {
$this->redirectAjax('/artists/view/' . $this->Artist->id);
}
}
$this->set(array(
'title_for_layout' => 'Add Artist',
'artistSections' => $this->Artist->ArtistSection->find('list', array('order' => 'name')),
'tags' => $this->Artist->Tag->find('list', array('order' => 'name'))
));
}
As I mentioned above, the saveAll method fails everytime. I have inspected what is getting output and Cake is outputting a bunch of blank <div>s with the error-message class, but there is no message. Every field on the form gets one of these divs.
Now, when I change my code to use the save function instead of saveAll, everything gets saved properly except the ArtistPreview data, which is to be expected. Even my HABTM Tags are being saved properly, and nothing fails validation.
I have been using Cake since the 1.3 days so I'm quite familiar with it, and have even done exactly what I'm asking in previous projects. I'm leaning towards this being a bug, unless I'm missing something here. Any ideas?
EDIT
I have also tried the saveAssociated method, along with setting the deep key to true when trying to save. This will let me save the artist, but it will not save the related data (ArtistPreview).
EDIT 2
As requested, here are the two tables:
-- -----------------------------------------------------
-- Table `artists`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `artists` ;
CREATE TABLE IF NOT EXISTS `artists` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`user_id` INT UNSIGNED NULL ,
`artist_section_id` INT UNSIGNED NULL ,
`artist_status_id` INT UNSIGNED NULL ,
`name` VARCHAR(200) NULL ,
`website` VARCHAR(500) NULL ,
`description` TEXT NULL ,
`date` DATETIME NULL ,
`comment_count` INT UNSIGNED NOT NULL DEFAULT 0 ,
PRIMARY KEY (`id`) ,
INDEX `FK_artists_users_idx` (`user_id` ASC) ,
INDEX `FK_artists__artist_sections_idx` (`artist_section_id` ASC) ,
INDEX `FK_artists__artist_statuses_idx` (`artist_status_id` ASC) ,
CONSTRAINT `FK_artists__users`
FOREIGN KEY (`user_id` )
REFERENCES `users` (`id` )
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT `FK_artists__artist_sections`
FOREIGN KEY (`artist_section_id` )
REFERENCES `artist_sections` (`id` )
ON DELETE SET NULL
ON UPDATE CASCADE,
CONSTRAINT `FK_artists__artist_statuses`
FOREIGN KEY (`artist_status_id` )
REFERENCES `artist_statuses` (`id` )
ON DELETE SET NULL
ON UPDATE CASCADE)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `artist_previews`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `artist_previews` ;
CREATE TABLE IF NOT EXISTS `artist_previews` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`artist_id` INT UNSIGNED NULL ,
`url` VARCHAR(500) NULL ,
`date` DATETIME NULL ,
PRIMARY KEY (`id`) ,
INDEX `FK_artist_previews__artists_idx` (`artist_id` ASC) ,
CONSTRAINT `FK_artist_previews__artists`
FOREIGN KEY (`artist_id` )
REFERENCES `artists` (`id` )
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
Here is my setData function, which just merges two arrays. Instead of using hidden fields, I set fields in the controller which aren't populated by user input:
public function setData(&$original, $new) {
$original = array_merge($original, $new);
}
$this->Model->validate, but I'll have to set the model data separately. When I pass the array with thedeepkey to the saveAll/saveAssociated methods, at least the artist gets saved. But it just doesn't want to save the related data. I'm going to perform a test with a clean install of Cake soon to see if it's a bug. - Hoff$this->setDatado? - Chuck Burgess