アソシエーションを用いたDoctrine 2具象テーブル継承

アソシエーションでDoctrine 2継承マッピングを読んだが、 > Animal が、オプションリストを作成するための独自のエンティティになるようにします。

この場合、 Pet のDiscriminator Columnは動物表の種別列にあります。

Pet Database Schema

だからクラスはこのようなものになるでしょう。

class Animal
{
    $id;
    $species;
}

/**
 * @Table(name="animal")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="species", type="string")
 * @DiscriminatorMap({"dog" = "Dog", "cat" = "Cat"})
 */
abstract class Pet
{
    $id
    $species;
}

class Dog extends Pet { }

class Cat extends Pet { }

class Owner 
{
    /**
     * @OneToMany(targetEntity="Pet")
     */
    $pets
}

私はいくつかの問題を見る。

  1. animal テーブルに owner への外部キーがありません。だから、 $ pets の関連付けは機能しません。

  2. Animal Pet は多かれ少なかれ同じものです。ある場合 それらの変更が Animal に反映されない 任意の Pet サブクラスです。

最初の問題の可能な解決策は、 pet という余分なテーブルを持つことですが、識別子の列がまだ動物にあるので、 pet に列を複製すると、正規化が中断されます。

enter image description here

4

1 答え

私はあなたの問題を完全に理解しているかどうかはわかりませんが、試してみましょう:

  • A Pet being an Animal, it makes sense to make it explicit in your class hierarchy. Note that the abstract class Pet can subclass the concrete class Animal. This way, you can still instantiate an Animal, a Dog or a Cat, but you can't instantiate a Pet;
  • The Animal root class can have its own discriminator value, which makes possible to persist it with Doctrine. You can then create and persist a Dog or a Cat, and even a generic Animal;
  • Animal needs a reference to its owner;
  • Owner now has a one-to-many relationship to Animal;
  • The species column is a discriminator, and adds no value to your domain model (the class name will tell you which Animal you're dealing with), so I would advise to remove this property.

最終的に、 Pet クラスが本当に必要ですか?ペットが Animal に特有のものがない(つまりクラスが空の)ものがない場合は、おそらくクラス階層から削除する必要があります。

class Owner {
    /**
     * @OneToMany(targetEntity="Animal")
     */
    protected $animals;
}

/**
 * @Table(name="animal")
 * @InheritanceType("JOINED")
 * @DiscriminatorColumn(name="species", type="string")
 * @DiscriminatorMap({"animal" = "Animal", "dog" = "Dog", "cat" = "Cat"})
 */
class Animal {
    /** @Id @Column(type="integer") @GeneratedValue */
    protected $id;

    /** @ManyToOne(targetEntity="Owner") */
    protected $owner;
}

abstract class Pet extends Animal {
   //Do you really need this class?
}

class Dog extends Pet {
   //...
}

class Cat extends Pet {
   //...
}

あなたのデータベース構造について、私は以下の変更を提案します:

  • Move owner_id from Dog & Cat to the Animal table;
  • Remove animal_id from the Dog & Cat tables; they'll share the id value with the Animal table (one-to-one).
3
追加された
PHP - 日本のコミュニティ [ja]
PHP - 日本のコミュニティ [ja]
4 参加者の

このグループではPHPについて話します。 パートナー:kotaeta.com