Propel オブジェクトから多対多の関連オブジェクトにアクセス

Propel が生成するオブジェクトは、foreign-key で関連づけられたオブジェクト(のリスト)を取得するためのメソッドを自動的に提供してくれます。しかし、多対多の関係に有る場合は中間オブジェクト(下記におけるTagged)しか取得できないので、中間テーブルからさらに関連オブジェクト(Tag)を取得する必要があります。

Bookmark ---<> Tagged <>--- Tag

これを簡単に実現する方法が「symfony で開発日記」に書かれているのですが、これが結構遅い*1
一つだけならまだいいのですが、例えば Bookmark を10件ずつリスト表示して、それぞれのブックマークにつけられたタグを表示なんてのをやろうとすると、後述する方法の倍くらいかかります。

Symfonyで開発日記 : 多対多テーブルを簡単に扱う
http://blog.symfony.jp/2006/12/29/sfpropelmanytomany/#more-96

ぼくの場合は、例えばこんな風に Bookmark を拡張して Tag オブジェクトを取得するようにしてます。

class Bookmark extends BaseBookmark {

 public function getTags()
 {
   $c = new Criteria();
 
   $c->addJoin(TagPeer::ID, TaggedPeer::TAG_ID);
   $c->add(TAGGED::BOOKMARK_ID, $this->getId());	
 
   return TagPeer::doSelect($c);
 }
}
	

DB へのクエリは変わらないんだけどな。

*1:ちなみに、スピードが遅くなる点についてはリンク先の記事でも指摘されてることです。