Bonjour,

J'ai une relation HABTM et j'aimerais sauvegarder à la mains les relations entre ces 2 tables, mais à chaque boucle de save(), chacune remplace la précédente, donc seule la dernière est vraiment sauvegarder

J'ai donc, pour le plus important :

ModelA:

public $hasAndBelongsToMany = array('ModelB');

public function add($1, $2) {

$this->clear();
$this->create();

$tab = array();
$tab'ModelA']'id'] = $1;
$tab'ModelB']'id'] = $2;

debug($tab); //J'ai bien ce que je veux

$this->save($tab); // Sauvegarde, mais remplace la précédente
//$this->saveAll($tab);

//$this->clear();
}

ModelB:

public $hasAndBelongsToMany = array('ModelA');

ControlleurA:

foreach(blabla):
debug($1); //J'ai bien ce que je veux
debug($2); //J'ai bien ce que je veux
$this->ModelA->add($1, $2);
endforeach;

Dans la fonction add, j'ai fait plusieurs test avec des create(), clear().. mais toujours pareil..
Mes 2 tables reliés sauvegardent bien leurs donnés sinon, seul la table de liaison déconne.

Quelqu'un a une solution ?

Merci

6 réponses


Zorexs
Auteur
Réponse acceptée

Merci, mais au final ça ne règle pas le problème de " l'auto-detection si existant ", il faut indiquer à la main en mettant l'id ou non.
Je ne comprend vraiment pas pourquoi Cake n’intègre pas ce système de base mais bon...

J'ai réussi à faire marcher ma méthode
En mettant la fonction dans le ModelB au lieu de ModelA et en ajoutant "'unique' => false" dans les HABTM des 2 model, ça passe

Je te suggères de te tourner vers la méthode saveAssociated, qui est faite pour ça : http://book.cakephp.org/2.0/fr/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array.

Depuis la 2.1 je crois qu'on peut faire ça avec un save classique en settant le paramètre deep à true, mais je ne l'ai jamais utilisé. A tester si tu le souhaites.

Zorexs
Auteur

Merci de ta réponse

Je l'avais vu sur la doc mais j'avais pas trouvé d'exemple pour les HABTM, jvois pas comment faire, si t'as une idée ?

Sinon en HABTM, un model "ModelAModelB" se génére ? Si oui, comment l'appeler ?

L'exemple couvre tout, les tables de liaison ne font pas partie des models, elles sont simplement là pour les lier entre eux, donc la mise à jour de cette table se fera automatiquement.

Extrait de la doc : When you do any HABTM operation other than adding a new one, Cake deletes and recreates the associated join table rows. All you have to do is get the record, remove the tag and save the record again.
Donc théoriquement, l'ensemble des liaisons HABTM de l'id courant du model A va être réécrite. Donc tu obtiens des données fraiches.

Je t'avoue que je ne comprends pas trop ta façon de coder, le fait de faire une méthode de classe alors que tu pourrais tout faire avec une action dans le controller. Donc le mieux, ce serait que tu nous donnes de la visibilité sur ta structure de table, sur ces deux modèles, et leurs controllers respectifs.

Zorexs
Auteur
$data = array(
    'ModelA' => array('name' => "nom"),
    'ModelB' => array(
        array('mail' => "test1"),
        array('mail' => "test2"),
        array('mail' => "test2"),
    ),
);
$this->ModelA->saveAssociated($data, array('deep' => true)); //Ne save que le ModelA
$this->ModelA->ModelB->saveAssociated($data, array('deep' => true)); //Ne save rien du tout

Je ne vois pas comment faire un saveAssociated() avec des HABTM...

Et le problème avec saveAssociation, enfaite, c'est que c'est surtout pour les cas où tu sauvegarde tout d'un coup, ce qui n'est pas mon cas puisque je fais beaucoup d'operations en même temps et surtout en plusieurs étapes(..., créations d'un ModelA, ..., ..., créations des ModelB puis relations)

Mais si on part par exemple avec un saveAll

$data = array(
    0 => array(
        "ModelA" => array(
            "id" => 1
    ),
        "ModelB" => array(
            "mail" => "test1"
        )
    ),
    1 => array(
        "ModelA" => array(
            "id" => 1
    ),
        "ModelB" => array(
            "mail" => "test2"
        )
    ),
    2 => array(
        "ModelA" => array(
            "id" => 1
        ),
        "ModelB" => array(
            "mail" => "test2"
        )
    )
);
$this->ModelA->create(array(
    'name' => "nom"
));
$this->ModelA->save();

$this->ModelA->ModelB->create();
$this->ModelA->ModelB->saveAll($data);

Donc avec 3 enregistrements de ModelB, dont 2 identiques
Je me retrouve avec le problème où je veux que lorsqu'il y a 2 identiques, au lieu de créer 2 ModelB : 1 seul est créé mais 2relations les lient, ce qui est la seule raison d'un HABTM
Ce que n'est pas le cas avec un saveAll, 2 ModelB se créait

Et lorsque j'indique une regles isUniq dans le ModelB, plus rien s'enregistre

//Que ce soit :
public $validate = array(
    'mail' => array(
        'rule' => 'isUnique'
    )
);
//Ou :
public $hasAndBelongsToMany = array('ModelA' => array('unique' => true));

J'ai trouvé ce guide qui m'a l'air plutôt bien fait et qui pourrait te débloquer face à ta situation : http://patisserie.keensoftware.com/fr/pages/how-to-save-habtm-data-in-cakephp