DEV

cakePHP アソシエーションの一括save

アソシエーション: モデル同士を繋ぐ参考

PostモデルとTagモデルがhasAndBelongsToManyの関係にあるとき、Postを登録する際に、$this->request->dataが、下記にようになっていれば一括登録できるようだ。

$this->request->data = array(
'Post' => array(
'title' => 'タイトル',
'content' => '内容',
'user_id' => 1
),
'Tag' => array(
'Tag' => array(
'0' => 1
)
)
);

Tagの1というのはtag_idです。 Viewでは、下記のように書けばいいようだ。

<?php echo $this->Form->create('Post'); ?>
<?php
echo $this->Form->input('title');
echo $this->Form->input('content');
echo $this->Form->input('user_id');
echo $this->Form->input('Tag');
?>
<?php echo $this->Form->end(__('Submit')); ?>

コントローラはこれだけで、HABTMのアソシエーションも一括登録してくれる。

public function add() {
if ($this->request->is('post')) {
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->Session->setFlash(__('The post has been saved'));
$this->redirect(array('action' => 'index'));
} else {
$this->Session->setFlash(__('The post could not be saved. Please, try again.'));
}
}
$users = $this->Post->User->find('list');
$tags = $this->Post->Tag->find('list');
$this->set(compact('users', 'tags'));
}

削除に関しても、Postを削除するときに、$this->Post->delete()とやるだけで、posts_tagsを一括削除してくれる。 もちろん、これらはModelのアソシエーション設定をしっかりしておくことが前提になる。

追加の一括登録時に、デフォルトではposts_tagsはユニークになるようになっていて、既にデータがある場合は削除してから、新たに追加するようだ。よって、もしposts_tagsなどの中間テーブルに各id以外の情報を登録している場合は、新たに追加する際に削除されてしまう。これを防ぐには、アソシエーション設定のuniqueに、trueではなく、keepExistingという文字列をセットする。これによって関連情報が削除されなくなるようだ。

ちなみに、Tag.idなのに、なんでTag.Tagなんだろうか?このTagは、アソシエーション設定の際のエイリアス名なんだけど、エイリアス名.エイリアス名にするのがルールなのかな??ViewのTagを、Tag.idにすると登録できなかった。TagをTag.Tagにすると登録できた。エイリアス名をTakoにして、TagをTakoにすると登録できて、TagをTako.Tagにすると登録できなかった。これからはおとなしく、viewではエイリアス名のみでいきます。