2

我有一个名为“talk”的表,它在我的 schema.xml 文件中定义为抽象。

它生成 4 个对象(每个类键 1 个):Comment、Rating、Review、Checkin

它也生成了TalkPeer,但我无法让它生成其他4个对等点(CommentPeer、RatingPeer、ReviewPeer、CheckinPeer),所以我手动创建了它们,并让它们继承自从BaseTalkPeer继承的TalkPeer.php。然后我在每个对等点中实现了 getOMClass()。

问题是,当我使用 4 个对等方进行查询时,它们会返回所有 4 种类型的对象。也就是说,ReviewPeer 将返回访问、评级、评论和评论。

例子:

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

这将返回值 > 5 的所有评论、评分、评论和签到。

ReviewPeer 应该只返回 Review 对象,并且无法弄清楚如何执行此操作。

我是否真的必须通过并更改所有标准才能手动指定类键?这似乎有点毫无意义,因为 Peer 名称已经不同了。我不想自定义每个 Peer。我应该能够自定义TalkPeer,因为它们都继承自它......我只是不知道如何。

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

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

文档谈到了覆盖 BaseTalkPeer::populateObject( ) 。我觉得这是我的问题,但即使在阅读了源代码之后,我仍然无法弄清楚如何让它工作。

这是我在 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 方法的示例:

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

这是我的架构的相关位:

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

4

2 回答 2

0

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

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);
}
于 2010-01-14T20:49:28.767 回答
0

为什么不删除 abstract=true 语句以便生成所有 Peers,然后再次添加摘要,再次生成以完全按照您的喜好获取数据库?

于 2010-01-22T15:46:30.633 回答