编辑Cakephp中的自引用HABTM有时会起作用

时间:2009-12-13 19:22:18

标签: cakephp save has-and-belongs-to-many self-reference

我正在使用参与者自我引用HABTM模型。您注册参加活动,当您登录到预订/个人资料时,您会看到其他参与者的列表,您可以选择将自己和其他人添加到各个组中;分享酒店房间,从机场分享交通等。

到目前为止我管理的内容:

1)在我的个人资料中,我看到所有其他参与者的列表以及复选框。到目前为止很棒。
2)添加其他参与者工作正常。下次编辑时,我添加的参与者显示为已选中 3)删除其他参与者也可以正常工作,只要您在提交之前仍然检查了参与者!

再次,用文字:

有3名参与者。我作为其中一个登录,我在参与者列表中看到另外两个人。我选择检查它们。这很好(总是)。后来我选择删除其中一个(通过取消选中复选框并点击提交)。这也很好(总是)。如果我想删除最后一个复选框...没有更新(总是!)。令人好奇的是,我可以添加和删除参与者的任何奇怪组合,它总是有效,除非我选择一次性删除每个参与者(删除一个且唯一的参与者是“删除所有已检查的参与者”的特殊情况)。 / p>

据我所知,HABTM首先删除所有关系,然后重新保存它们。我可以在我的表中看到,当我删除,添加,删除,反复添加相同的参与者时 - HABTM表上的ID总是在增加。但是,当我一次取消选择所有参与者时,关系更新。 ids保持不变,所以就像保存从未发生过一样。

这种行为是如此具体和特殊,我有一种感觉,我在这里遗漏了一些明显的东西。无论如何,这是相关的代码:

模型

class Participant extends AppModel {
 var $hasAndBelongsToMany = array(
  'buddy' => array(
   'className' => 'Participant',
   'joinTable' => 'participants_participants',
   'foreignKey' => 'participant_id',
   'associationForeignKey' => 'buddy_id',
   'unique' => true,
  )
 );

控制器

function edit($id = null) {
 if (!$id && empty($this->data)) {
  $this->Session->setFlash(__('Invalid Participant', true));
  $this->redirect(array('action'=>'index'));
 }
 if (!empty($this->data)) {
  if ($this->Participant->saveAll($this->data)) {
   $this->Session->setFlash(__('The Participant has been saved', true));
   $this->redirect(array('action'=>'index'));
  } else {
   $this->Session->setFlash(__('The Participant could not be saved. Please, try again.', true));
  }
 }
 if (empty($this->data)) {
  $this->data = $this->Participant->read(null, $id);
 }

 // Fetching all participants except yourself
 $allParticipants = $this->Participant->find('list', array('conditions' => array('participant.id ' => $id)));

 // Fetching every participant that has added you to their list
 $allBuddies = $this->Participant->ParticipantsParticipant->find('list', array(
  'conditions' => array('buddy_id' => $id),
  'fields' => 'ParticipantsParticipant.participant_id',
  'order' => 'ParticipantsParticipant.participant_id ASC'
 ));

 $this->set(compact('allParticipants','allBuddies'));
}

查看

    echo $form->create('Participant');
    echo $associations->habtmCheckBoxes($allParticipants, $this->data['buddy'], 'buddy', 'div', '\'border: 1px solid #000;\'', '\'border: 1px solid #000;\'');
    echo $form->end('Submit');

我正在使用一个稍微修改过的帮助器habtmCheckBoxes,在这里找到:http://cakeforge.org/snippet/detail.php?type=snippet&id=190 它的工作原理如下:function habtmCheckBoxes($ rows = array(),$ selectedArr = array(),$ modelName,$ wrapTag ='p',$ checkedDiv,$ uncheckedDiv){}

1 个答案:

答案 0 :(得分:0)

这是因为HABTM在CakePHP中的工作方式 - 如果数组中存在HABTM密钥,它只会保存HABTM数据。因此,当没有选中复选框时,没有数据通过,而蛋糕也没有触及您现有的habtm记录。

快速解决方法是向控制器添加几行代码。

if (!empty($this->data)) {
  if (empty($this->data['buddy'])) {
    $this->data['buddy'] = array('buddy' => array(''));
  }
  if ($this->Participant->saveAll($this->data)) {
   // ...
  } else {
   // ...
  }
}

但是,如果您也可以使用cake的表单助手(而不是您正在使用的其他帮助程序)在您的视图中执行此操作:

echo $form->inputs(array(
    'legend' => 'Nominate your artwork for awards',
    'buddy' => array('label' => false, 'multiple' => 'checkbox', 'options' => $allBuddies)
));