2

さまざまなタイプのオブジェクトのキーと値のペアを格納できる単純なポリモーフィック属性テーブルを作成しようとしています。単一テーブル継承を使用すると、これが私の現在の構成です。

/**
 * @Entity @Table(name="attributes")
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="subject", type="string")
 * @DiscriminatorMap({"page" = "PageAttribute", "product" = "ProductAttribute"})
 */
class PageAttribute
{
    /**
     * @ManyToOne(targetEntity="Page", inversedBy="attributes")
     * @JoinColumn(name="subject_id", referencedColumnName="id")
     */
    private $page;
}

/**
 * @Entity @Table(name="attributes")
 */
class ProductAttribute extends PageAttribute
{
    /**
     * @ManyToOne(targetEntity="Product", inversedBy="attributes")
     * @JoinColumn(name="subject_id", referencedColumnName="id")
     */
    private $product;
}

問題は、このスキーマがロードされるときに、subject_id列がページテーブルにリンクする外部キー制約を使用して作成されることです。

subject_idをすべての外部キーに使用できるように、この制約を防ぐ方法はありますか?それ以外の場合は、オブジェクトのタイプごとに列を作成する必要がありますが、これは避けようとしています。

4

1 に答える 1

1

これと同じ問題がありました。これが私がそれを解決した方法です:

/**
 * @Entity @Table(name="attributes")
 */
class ProductAttribute extends PageAttribute
{
    public static function getSubject() {
        return 'product';
    } 
    /**
     * @ManyToOne(targetEntity="Product", inversedBy="attributes")
     * @JoinColumn(name="product_id", referencedColumnName="id")
     */
    private $product;
}

つまり、subject_id を使用してすべてのエンティティを参照する代わりに、エンティティの種類ごとに個別の結合列を使用します。次に、静的関数を使用して、「件名」列のパラメーター名を取得できます。

たとえば、次のようになります。

$subject = $genericPageAttribute->{$genericPageAttribute::getSubject()};

この場合、"Product" のインスタンスを返します。

このソリューションをさらに改善するために、すべての「サブジェクト」が実装できるインターフェースを作成することをお勧めします。

これがすべてのケースをカバーするかどうかはわかりませんが、これまでのところうまくいくようです。

どのように機能するか (または機能しないか) を教えてください。

于 2012-12-05T18:17:43.253 に答える