2

schema.xml ファイルで抽象として定義されている「talk」というテーブルがあります。

4 つのオブジェクト (クラスキーごとに 1 つ) を生成します: コメント、評価、レビュー、チェックイン

TalkPeer も生成しますが、他の 4 つのピア (CommentPeer、RatingPeer、ReviewPeer、CheckinPeer) は生成できなかったので、手動で作成し、BaseTalkPeer を継承する TalkPeer.php を継承するようにしました。次に、これらの各ピアに getOMClass() を実装しました。

問題は、4 つのピアを使用してクエリを実行すると、4 つのタイプのオブジェクトすべてが返されることです。つまり、ReviewPeer は Visits、Ratings、Comments、および Reviews を返します。

例:

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

これにより、値が 5 を超えるすべてのコメント、評価、レビュー、およびチェックインが返されます。

ReviewPeer は Review オブジェクトのみを返す必要があり、これを行う方法がわかりません。

クラスキーを手動で指定するには、実際にすべての基準を調べて変更する必要がありますか? Peer の名前はすでに異なるため、これは少し無意味に思えます。各ピアをカスタマイズする必要はありません。TalkPeer はすべて継承しているので、TalkPeer だけをカスタマイズできるはずです...方法がわかりません。

TalkPeer だけで doSelectStmt を変更して、自動的に CLASSKEY 制限を基準に追加しようとしました。それはほとんど動作しますが、次のように表示されます: Fatal error: Cannot instantiate abstract class Talk in /models/om/BaseTalkPeer.php on line 503. Line 503 is in BaseTalkPeer::populateObjects(), and is in the 3rd line below:

$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

abstract=true ステートメントを削除して、すべてのピアを生成してから、abstract を再度追加し、再度生成して、好きなように正確にデータベースを取得してみませんか?

于 2010-01-22T15:46:30.633 に答える
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 に答える