1

私はSymfony2とDoctrine2で小さなウェブサイトを構築しています。ブログ投稿、イベント、プレスリリースがあります。これらはどれも非常に似ているため、「ノード」という親テーブルで単一テーブル継承(STI)を使用することにしました。

ノードには次のものがあります。

  • ブール値である「公開済み」フィールド
  • 「ロケール」フィールド。これは文字列であり、「これはこのロケールでのみ表示されます」と表示されます。(ロケールはリクエストを介して渡されます)。

デフォルトでは、現在のロケールからの公開済みノードのみを表示したいと思います。

明らかに、次のような多くのクエリをリポジトリに作成できます。

$this->createQueryBuilder('Event')
     ->where('Node.published = 1')
     ->where('Node.locale = :locale')

しかし、これはあまり乾燥していないようです。

では、他のクエリが「継承」できるデフォルトのクエリを作成するにはどうすればよいですか?これには、リレーションに基づくデフォルトのDoctrineクエリを含める必要があります。

4

2 に答える 2

4

継承はおそらくやり過ぎです。

事前構成されたqueryBuilderを提供する小さなファクトリメソッドを作成してみませんか?

class NodeRepository extends Doctrine\ORM\EntityRepository {

    public function getLocalizedNodeQueryBuilder($type,$locale){
        return $this->getQueryBuilder($type)
            ->where('Node.published = 1')
            ->where('Node.locale = :locale')
            ->setParameter('locale',$locale);
    }
}

同じことを行うことができます。クエリビルダーを常にそのように構成する必要がある場合は、getQueryBuilderをオーバーライドするだけです。

于 2012-05-08T20:39:56.873 に答える
2

そのようなものをリポジトリクラスに組み込む必要はありません。「ディスクリミネーターマップ」を使用して単一テーブル継承を設定すると、個別のクラス(エンティティ)になります。Doctrineは、DBALと対話するときに、「ノードタイプ」によるフィルタリングを処理します。

http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/inheritance-mapping.html#single-table-inheritance

例えば..

namespace MyProject\Model;

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"node" = "Node", "blogpost" = "Blogpost", "events" = "Events"})
 */
class Node
{
    // ...
}

/**
 * @Entity
 */
class Blogpost extends Node
{
    // ...
}

/**
 * @Entity
 */
class Events extends Node
{
    // ...
}


// get me all the blogposts
$blogposts = $em->getRepository('Blogpost')->findAll();

// get me all the events
$events = $em->getRepository('Events')->findAll();

これは、親クラス「Node」で表現しようとするのではなく、「Blogpost」ロジックを独自のエンティティにカプセル化できるため、特に有益です。

于 2012-05-08T13:46:49.600 に答える