在cakephp作品中编辑自我引用HABTM,有时候

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

到目前为止我所管理的是:

1)在我的个人资料中,我看到所有其他参与者的复选框列表。 太好了。
2)添加另一名参与者工作正常。 下次我编辑时,我添加的参与者显示为已选中。
3)只要您在提交之前仍检查了参与者,移除另一位参与者就可以正常工作!

再一次,用文字:

有3个参与者。 我以其中之一的身份登录,并在参与者列表中看到另外两个人。 我选择检查他们两个。 这工作正常(总是)。 稍后,我选择删除其中的一个(通过取消选中复选框并点击提交)。 这也工作得很好(总是)。 如果我想删除最后一个复选框......没有更新(总是!)。 奇怪的是,我可以添加和删除任何奇怪的参与者组合,并且它将始终有效。除非我选择一次移除每个参与者(删除一个参与者并且是唯一参与者是“删除所有参与者”的特殊情况)。

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

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

模型

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){}


这是因为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)
));
链接地址: http://www.djcxy.com/p/64873.html

上一篇: Edit of self referencing HABTM in cakephp works, sometimes

下一篇: How to convert string as stdClass object to array [PHP]