推进单表继承问题 [英] Propel Single Table Inheritance Issue

查看:98
本文介绍了推进单表继承问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为对话"的表,该表在我的schema.xml文件中定义为抽象的.

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

它生成4个对象(每个类键1个):评论,评分,审阅,签入

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

它还会生成TalkPeer,但我无法生成其他4个对等体(CommentPeer,RatingPeer,ReviewPeer,CheckinPeer),因此我手动创建了它们,并使它们继承自TalkPeer.php,后者继承自BaseTalkPeer.然后,我在每个对等端中实现了getOMClass().

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.

问题是,当我使用4个同级进行查询时,它们返回所有4种类型的对象.也就是说,ReviewPeer将返回访问次数,评分,评论和评论.

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.

示例:

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

这将返回所有评论,评分,评论和&值大于5的签到.

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

ReviewPeer应该只返回Review对象,而不能计算 了解如何执行此操作.

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

我是否真的必须经历并更改所有标准以手动指定类密钥? 这似乎没有意义,因为Peer名称已经不同. 我不想自定义每个Peer.我应该能够自定义TalkPeer,因为它们都继承自它...我只是不知道怎么做.

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.

我尝试仅在TalkPeer中更改doSelectStmt,以便它自动将CLASSKEY限制添加到条件中.它几乎可以正常工作,但是我得到一个:致命错误:无法实例化第503行的/models/om/BaseTalkPeer.php中的抽象类Talk.第503行位于BaseTalkPeer :: populateObjects()中,位于下面的第三行:

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

文档讨论了重写BaseTalkPeer :: populateObject(). 我觉得这是我的问题,但是即使阅读了源代码,我仍然不知道如何使它工作.

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.

这是我在TalkPeer :: doSelectStmt:

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

这是我来自ReviewPeer的getOMClass方法的一个示例:

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. -不,我不能从1.3升级到1.4.太多了 需要重新测试的代码

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

推荐答案

我从未在Propel中使用继承,但是您应该能够在每个Peer类上修改doSelectRS方法以修改条件并为继承密钥指定额外条件.我前面没有文档,但在伪代码中看起来像这样:

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

这篇关于推进单表继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆