Propel Single Table Inheritance Issue

大城市里の小女人 提交于 2019-12-09 22:45:01

问题


I have a table called "talk", which is defined as abstract in my schema.xml file.

It generates 4 objects (1 per classkey): Comment, Rating, Review, Checkin

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.

The problem is 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.

Example:

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

This returns all comments, ratings, reviews, & checkins that have a value > 5.

ReviewPeer should only return Review objects, and can't figure out how to do this.

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.

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:

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

The docs talked about overriding BaseTalkPeer::populateObject(). I have a feeling that's my problem, but even after reading the source code, I still couldn't figure out how to get it to work.

Here is what I tried in 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);
    }

Here is an example of my getOMClass method from ReviewPeer:

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

Here is the relevant bit of my schema:

<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>

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


回答1:


Why don't you just remove the abstract=true statements so you generate all Peers, then add the abstract again, generate again to get the db exactly as you like it?




回答2:


Ive never used inheritance in Propel but you should be able to modify the doSelectRS methods on each Peer class to modify the criteria and specify the extra condition for the inheritance key. I dont have the docs in front of me but in pseudo code itd look something like this:

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);
}


来源:https://stackoverflow.com/questions/2067354/propel-single-table-inheritance-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!