0 votes

Relation CakePHP belongsTo avec un champ variable 'model'.

J'ai un problème avec une relation belongsTo dans CakePHP.

J'ai un modèle "Action" qui utilise la table "actions" et appartient à l'un des deux autres modèles, "Transaction" ou "Tag". L'idée est que chaque fois qu'un utilisateur effectue une transaction ou ajoute une balise, le modèle d'action est créé pour en garder une trace. J'ai réussi à faire fonctionner cette partie, chaque fois qu'une transaction ou un tag est sauvegardé, la méthode aftersave() ajoute également un enregistrement d'action. Le problème est que lorsque j'essaie de faire un find('all') sur le modèle d'action, l'enregistrement de la transaction ou du tag correspondant n'est pas renvoyé.

actions :

id
model
model_id
created

Je pensais que je pouvais utiliser le paramètre "conditions" dans la relation belongsTo comme ceci :

<?php
class Action extends AppModel {

var $name = 'Action';
var $actsAs = array('Containable');
var $belongsTo = array(
    'Transaction' => array(
        'foreignKey' => 'model_id',
        'conditions' => array("Action.model"=>"Transaction")
    ),
    'User' => array(
        'fields' => array('User.username') 
    ),
    'Recommendation' => array(
        'conditions' => array("Action.model"=>"Recommendation"),
        'foreignKey' => 'model_id'
    )
);  
}
?>

Mais ça ne marche pas.

Est-ce que quelque chose m'échappe, mes relations sont-elles fausses (je le soupçonne) ? Après avoir cherché ce problème sur Google, je suis tombé sur un outil appelé Comportement polymorphe mais je ne suis pas sûr que cela m'aidera.

4voto

Rob Wilkerson Points 12220

Si je comprends bien, il semble que le comportement polymorphe soit une excellente réponse. Il vous permet de lier un Action vers tout autre modèle (dans votre cas, un Transaction o Tag ). Si vous récupérez ensuite un Action --et si ma mémoire est bonne (je ne l'ai utilisé qu'une seule fois), alors le modèle associé reviendra également (en supposant que l'option appropriée soit activée). recursive ).

À titre d'exemple, dans un projet récent, j'ai construit une Alert modèle. Les alertes pouvaient être attachées à n'importe quel modèle. Tout enregistrement d'alerte donné identifiait le modèle auquel il appartenait et l'ID d'enregistrement approprié :

class Alert extends AppModel {
  public $actsAs    = array (
    'Polymorphic' => array (
      'classField' => 'model',
      'foreignKey' => 'entity_id'
    )
  );

  # Additional model code
}

Et ma table a été construite selon les spécifications suivantes :

CREATE TABLE alerts (
  id CHAR(36) NOT NULL,
  alert_template_id VARCHAR(255) NOT NULL,
  model VARCHAR(255) NOT NULL,
  entity_id CHAR(36) NOT NULL,
  valid_from BIGINT NULL,
  valid_to BIGINT NULL,
  replacement_keys TEXT NULL,
  active BOOL NOT NULL DEFAULT 0,
  created BIGINT NOT NULL,
  updated BIGINT NOT NULL,
  PRIMARY KEY(id),
  FOREIGN KEY(alert_template_id)
    REFERENCES alert_templates(id)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION
)TYPE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

Notez le entity_id y model champs. Pour chaque Alert qui contiennent un identifiant unique et un nom de modèle (par ex. User ), respectivement. Il semble que cela répondrait parfaitement à vos besoins.

0voto

JanWillem Points 177

Donc, si je ne me trompe pas, vous voulez sauvegarder automatiquement les données dans le tableau des actions ? Peut-être que d'autres utilisateurs vous répondront que c'est possible, mais pour autant que je sache, ce n'est pas le cas.

Il serait peut-être bon d'examiner la fonction de rappel du modèle "afterSave()". Ici, vous pouvez effectuer un save() après que l'autre requête ait été effectuée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X