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é
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. –
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
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(); –