2009-12-13 12 views
0

J'utilise un modèle HABTM auto-référencé avec les participants. Vous vous inscrivez à un événement et lorsque vous vous connectez à votre réservation/profil, vous voyez une liste d'autres participants et vous pouvez choisir de vous ajouter et d'ajouter d'autres personnes dans divers groupes; part chambre d'hôtel, le transport part de l'aéroport, etc.Modification de l'auto-référencement HABTM dans les travaux de cakephp, parfois

Ce que j'ai réussi jusqu'à présent:

1) Dans mon profil, je vois la liste de tous les autres participants avec des cases à cocher. Super jusqu'à présent.
2) L'ajout d'un autre participant fonctionne correctement. La prochaine fois que je modifie, le participant que j'ai ajouté est affiché comme coché.
3) La suppression d'un autre participant fonctionne bien aussi longtemps que vous avez encore vérifié les participants avant de soumettre!

Encore une fois, avec les mots:

Il y a 3 participants. Je suis connecté en tant que l'un d'entre eux, et je vois les 2 autres personnes sur la liste des participants. Je choisis de vérifier les deux. Cela fonctionne bien (toujours). Plus tard, je choisis de supprimer l'un d'entre eux (en décochant la case et en appuyant sur Envoyer). Cela fonctionne aussi bien (toujours). Si je veux enlever la dernière case à cocher ... rien n'est mis à jour (toujours!). Ce qui est curieux, c'est que je peux ajouter et supprimer n'importe quelle combinaison de participants et cela fonctionnera SAUF si je choisis de supprimer tous les participants en une fois (en supprimant un et un seul participant est un cas spécial de "supprimer tous les participants vérifiés"). Pour autant que je sache, les HABTM fonctionnent en supprimant d'abord toutes les relations, puis en les réenregistrant. Je peux voir cela dans mes tableaux quand je supprime, ajoute, supprime, ajoute le même participant encore et encore - l'identifiant de la table HABTM augmente toujours. Lorsque je désélectionne tous les participants à la fois, les relations sont et non mises à jour. Les identifiants restent les mêmes, c'est comme si la sauvegarde n'avait jamais eu lieu.

Ce comportement est si spécifique et si particulier, j'ai le sentiment qu'il me manque quelque chose d'évident ici. Quoi qu'il en soit, voici le code correspondant:

Modèle

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

Contrôleur

 
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')); 
} 

Voir

 
    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'); 

J'utilise une aide légèrement modifiée, habtmCheckBoxes, trouvé ici: http://cakeforge.org/snippet/detail.php?type=snippet&id=190 Cela fonctionne comme ceci: function habtmCheckBoxes ($ rows = array() $ selectedArr = array(), $ modelName, $ wrapTag = 'p', $ checkedDiv, $ uncheckedDiv) {}

Répondre

0

Cela se produit en raison de la façon dont HABTM fonctionne dans CakePHP - il ne sauvegarde les données HABTM que si le HABTM La clé existe dans le tableau. Par conséquent, lorsqu'aucune case à cocher n'est cochée, aucune donnée n'est transmise et le gâteau ne touche pas vos enregistrements habtm existants.

Une solution rapide serait d'ajouter quelques lignes de code à votre contrôleur.

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

Cependant, si peut-être aussi possible pour vous d'utiliser assistant formulaire de gâteau (au lieu de l'aide que vous utilisez) pour ce faire à votre avis:

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

Oui!J'ai lu quelque part pour "définir l'id à NULL" en travaillant avec habtm mais je n'ai jamais compris comment cela a fonctionné. Je suppose que c'est ce que tu as fait maintenant. Merci beaucoup! –