Note that there are some explanatory texts on larger screens.

plurals
  1. POPropel Single Table Inheritance Issue
    text
    copied!<p>I have a table called "talk", which is defined as abstract in my schema.xml file.</p> <p>It generates 4 objects (1 per classkey): Comment, Rating, Review, Checkin</p> <p>It also generates TalkPeer, but I couldn't get it to generate the other 4 peers (CommentPeer, RatingPeer, ReviewPeer, CheckinPeer), so I created them by hand, and made them inherit from TalkPeer.php, which inherits from BaseTalkPeer. I then implemented getOMClass() in each of those peers.</p> <p><strong>The problem is</strong> that when I do queries using the 4 peers, they return all 4 types of objects. That is, ReviewPeer will return Visits, Ratings, Comments, AND Reviews.</p> <p><strong>Example:</strong></p> <pre><code>$c = new Criteria(); $c-&gt;add(RatingPeer::VALUE, 5, Criteria::GREATER_THAN); $positive_ratings = RatingPeer::doSelect($c); </code></pre> <p>This returns all comments, ratings, reviews, &amp; checkins that have a value > 5.</p> <p><strong>ReviewPeer should only return Review objects, and can't figure out how to do this.</strong></p> <p>Do I actually have to go through and change all my criteria to manually specify the classkey? That seems a little pointless, since the Peer name already distinct. I don't want to have to customize each Peer. I should be able to customize JUST the TalkPeer, since they all inherit from it... I just can't figure out how.</p> <p>I tried changing doSelectStmt just in TalkPeer so that it automatically adds the CLASSKEY restriction to the Criteria. It almost works, but I get a: Fatal error: Cannot instantiate abstract class Talk in /models/om/BaseTalkPeer.php on line 503. Line 503 is in BaseTalkPeer::populateObjects(), and is the 3rd line below: </p> <pre><code>$cls = TalkPeer::getOMClass($row, 0); $cls = substr('.'.$cls, strrpos('.'.$cls, '.') + 1); $obj = new $cls(); </code></pre> <p>The <a href="http://propel.phpdb.org/trac/wiki/Users/Documentation/1.3/Inheritance" rel="nofollow noreferrer">docs talked about overriding BaseTalkPeer::populateObject()</a>. <strong>I have a feeling that's my problem</strong>, but even after reading the source code, I still couldn't figure out how to get it to work.</p> <p>Here is what I tried in TalkPeer::doSelectStmt:</p> <pre><code> public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null) { $keys = array('models.Visit'=&gt;1,'models.Comment'=&gt;2,'models.Rating'=&gt;3,'models.Review'=&gt;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-&gt;add(TalkPeer::CLASS_KEY, $class_key); } return parent::doSelectStmt($criteria, $con = null); } </code></pre> <p>Here is an example of my getOMClass method from ReviewPeer:</p> <pre><code>public static function getOMClass() { return self::CLASSNAME_4; //aka 'talk.Review'; } </code></pre> <p>Here is the relevant bit of my schema:</p> <pre><code>&lt;table name="talk" idMethod="native" abstract="true"&gt; &lt;column name="talk_pk" type="INTEGER" required="true" autoIncrement="true" primaryKey="true" /&gt; &lt;column name="class_key" type="INTEGER" required="true" default="" inheritance="single"&gt; &lt;inheritance key="1" class="Visit" extends="models.Talk" /&gt; &lt;inheritance key="2" class="Comment" extends="models.Talk" /&gt; &lt;inheritance key="3" class="Rating" extends="models.Talk" /&gt; &lt;inheritance key="4" class="Review" extends="models.Rating" /&gt; &lt;/column&gt; &lt;/table&gt; </code></pre> <p>P.S. - No, I can't upgrade from 1.3 to 1.4. There's just too much code that would need to be re-tested</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload