2010-01-14 6 views
2

J'ai une table appelée "talk", qui est définie comme abstraite dans mon fichier schema.xml.Propel Héritage de table unique Problème

Il génère 4 objets (1 par ClassKey): Commentaire, Note, Critique, Checkin

Il génère également TalkPeer, mais je ne pouvais pas l'obtenir pour générer les 4 autres pairs (CommentPeer, RatingPeer, ReviewPeer, CheckinPeer), donc je les ai créés à la main, et les ai fait hériter de TalkPeer.php, qui hérite de BaseTalkPeer. J'ai ensuite implémenté getOMClass() dans chacun de ces pairs.

Le problème est que lorsque je fais des requêtes en utilisant les 4 pairs, ils retournent tous les 4 types d'objets. En d'autres termes, ReviewPeer renvoie les visites, les évaluations, les commentaires et les avis.

Exemple:

$c = new Criteria(); 
$c->add(RatingPeer::VALUE, 5, Criteria::GREATER_THAN); 
$positive_ratings = RatingPeer::doSelect($c); 

Cela renvoie tous les commentaires, notes, avis, & checkins qui ont une valeur> 5.

ReviewPeer ne doit retourner des objets d'examen, et ne peut pas figure comment faire cela.

Est-ce que je dois réellement passer par tous mes critères pour spécifier manuellement la classe clé? Cela semble un peu inutile, puisque le nom Peer déjà distinct. Je ne veux pas avoir à personnaliser chaque pair. Je devrais pouvoir customiser juste le TalkPeer, puisqu'ils héritent tous de lui ... Je ne peux juste pas comprendre comment.

J'ai essayé de changer doSelectStmt juste dans TalkPeer afin qu'il ajoute automatiquement la restriction CLASSKEY aux critères. Cela fonctionne presque, mais j'ai un: Erreur fatale: Impossible d'instancier la classe abstraite Talk dans /models/om/BaseTalkPeer.php sur la ligne 503. La ligne 503 est dans BaseTalkPeer :: populateObjects(), et est la troisième ligne ci-dessous:

$cls = TalkPeer::getOMClass($row, 0); 
$cls = substr('.'.$cls, strrpos('.'.$cls, '.') + 1); 
$obj = new $cls(); 

Le docs talked about overriding BaseTalkPeer::populateObject(). J'ai le sentiment que c'est mon problème, mais même après avoir lu le code source, je n'arrivais toujours pas à comprendre comment le faire fonctionner.

Voici ce que j'ai essayé dans TalkPeer :: doSelectStmt:

public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) 
    { 
     $keys = array('models.Visit'=>1,'models.Comment'=>2,'models.Rating'=>3,'models.Review'=>4); 

     $class_name = self::getOMClass(); 

     if(isset($keys[$class_name])) 
     { //Talk itself is not a returnable type, so we must check 
      $class_key = $keys[$class_name]; 
      $criteria->add(TalkPeer::CLASS_KEY, $class_key); 
     } 

     return parent::doSelectStmt($criteria, $con = null); 
    } 

Voici un exemple de ma méthode de getOMClass de ReviewPeer:

public static function getOMClass() 
{ 
    return self::CLASSNAME_4; //aka 'talk.Review'; 
} 

Voici le bit correspondant de mon schéma:

<table name="talk" idMethod="native" abstract="true"> 
    <column name="talk_pk" type="INTEGER" required="true" autoIncrement="true" primaryKey="true" /> 
    <column name="class_key" type="INTEGER" required="true" default="" inheritance="single"> 
     <inheritance key="1" class="Visit" extends="models.Talk" /> 
     <inheritance key="2" class="Comment" extends="models.Talk" /> 
     <inheritance key="3" class="Rating" extends="models.Talk" /> 
     <inheritance key="4" class="Review" extends="models.Rating" /> 
     </column> 
</table> 

PS - Non, je ne peux pas passer de 1.3 à 1.4. I12 n'a jamais utilisé l'héritage dans Propel mais vous devriez être capable de modifier les méthodes doSelectRS sur chaque classe Peer pour modifier les critères et spécifier la condition supplémentaire pour l'héritage. Il y a trop de code qui aurait besoin d'être re-testé

Répondre

0

clé.Je n'ai pas les documents devant moi, mais dans le code pseudo ITD ressembler à quelque chose comme ceci:

public static function doSelectRS(Criteria $c) 
{ 
    // you may want to check if the condition already exists in one of the criterion's before doing the following... 
    $c->add(RatingPeer::TYPE, 3); 
    return parent::doSelectRS($c); 
} 
+0

Aucun des docs officiels ne mentionne cela, et j'aimerais éviter de personnaliser chaque pair si cela est possible. Lorsque je fais affaire avec Propel, j'en suis venu à croire que moins de personnalisation = moins de bugs. –

+0

haha ​​oh je suis d'accord. et la façon dont les docs lisent, ça sonne comme si vous faisiez tout correctement. la partie ambiguë est le cœur de votre problème (par exemple, est-ce qu'on s'attend à ce qu'ils retournent toutes les sous-classes que vous rencontrez ou sont supposées ne renvoyer que la sous-classe pour le pair utilisé). Je ne pense pas que cela a quelque chose à voir avec les objets de remplissage - je pense que c'est pour si vous voulez seulement les propriétés qui s'appliquent à un ensemble de sous-classes donné dans l'entité. Je ne dispose pas d'un projet propel mis en place - pensez-vous que vous pouvez poster le corps de 'populateObjects' et' doSelect'? – prodigitalson

+0

Je pense que doSelectRS est une chose Propel 1.2. Je m'en souviens, mais il ne figure nulle part dans ma base de code 1.3 :(J'essaie cependant une variante de votre suggestion, en modifiant doSelectStmt Cela fonctionne presque, mais j'ai: Erreur fatale: Impossible d'instancier la classe abstraite Talk in/models /om/BaseTalkPeer.php à la ligne 503. Ligne 503 est dans BaseTalkPeer :: populateObjects(), et est la troisième ligne ci-dessous: $ cls = TalkPeer :: getOMClass ($ row, 0); $ cls = substr (' $ cls, strrpos ('.'. $ cls, '.') + 1); $ obj = new $ cls(); –

0

Pourquoi ne pas supprimer simplement les déclarations abstraites = true si vous générez tous les pairs, puis ajouter le résumé à nouveau, générer à nouveau pour obtenir la DB exactement comme vous l'aimez?

+0

Que j'utilise "abstract" ou non, les Peers ne sont pas générés automatiquement. Aussi, le DB * est * exactement comme je l'aime. La partie "abstraite" est juste là pour que l'objet Talk & Peer ne soient pas utilisés directement, car le Talk doit être d'un type spécifique (Review/Rating/Visit/Comment). –

Questions connexes