Doctrine2をORMとして使用して、Symfony2のバンドル間でエンティティを適切に拡張する方法を見つけるのに問題があります。
現在、Doctrine2をORMとして使用してSymfony2のエンティティを拡張する方法が3つあります。Mapped Superclass
、Single Table Inheritance
およびClass Table Inheritance
。これらのどれも私がやろうとしていることのために働きません。
UserBundleとBlogBundleの2つのバンドルがあります。BlogBundleがないプロジェクトでUserBundleを使用できるようにしたいのですが、BlogBundleは常にUserBundleがあるプロジェクトで使用されます。BlogBundleがUserBundleに依存していても問題ありませんが、その逆は問題ありません。
BlogBundle \ Entity\PostとUserBundle\Entity\Userの2つのエンティティがあります
関係: ユーザーとブログ投稿の間には1対多の関係が必要です。これは、UserBundle \ Entity \User.idにマップされているBlogBundle\Entity \ Postオブジェクト(テーブル)のAuthor_IDプロパティ(列)を介して実現されます。
問題: BlogBundle内から直接UserBundle \ Entity \ Userエンティティを呼び出し、単方向マッピングを使用して探しているものを実現できます。これでは、Userオブジェクト内からユーザーによるすべての投稿にアクセスすることはできません。カスタムクエリを介してデータにアクセスできますが、これはユーザーオブジェクトを介してユーザーが投稿にアクセスするほどクリーンではありません。
私がやりたいのは、BlogBundle内からUserBundle \ Entity \ Userオブジェクトを拡張し、BlogBundle内で使用される1対多のマッピングを確立するメソッドとプロパティをこのオブジェクトに追加することです。これは永続化されません。関係を定義するだけで、ブログバンドル内のUserオブジェクトに必要な機能を追加することで、BlogBundleとUserBundleの両方を実装するアプリケーションでユーザーが作成したすべての投稿に論理的にアクセスできます(したがって、依存関係を回避できます)。 UserBundleからBlogBundleへ)。
BlogBundle \ Entity \ Userオブジェクトを作成し、UserBundle \ Entity \ Userを拡張するときは、@ ORM \ Table(name = "usertablename")を宣言する必要があります。そうしないと、BlogBundle \ Entity\Userオブジェクトにアクセスしようとしてもデータベースにアクセスできなくなります。拡張オブジェクトの追加は持続しないため、これはバンドル間で正常に機能します。これに関する問題は、「php app / console doctrine:schema:update --force」を呼び出すと、2つのエンティティが同じテーブルにマップして作成しようとするため、競合が発生することです。最近実装されたResolveTargetEntityListener機能を使用してみましたが、これは、マップされたSuperclas、STI、およびCTIとともに、UserBundleからBlogBundleへの依存を強制します。
以下は、私のセットアップを説明するのに役立つ私のオブジェクトです。わかりやすくするために省略されています。セマンティクスの一部が正しくないことに気付きましたが、それはアイデアと構成を伝えることを目的としています。
UserBundle \ Entity \ User
@ORM\Table(name="app_user")
@ORM\Entity
class User implements UserInterface
{
...
}
BlogBundle \ Entity \ Post
@ORM\Table(name="app_post")
@ORM\Entity
class Post
{
...
@ORM\Column(name="author_id", type="integer")
protected $author_id;
@ORM\ManyToOne(targetEntity="\App\BlogBundle\Entity\User", inversedBy="posts")
@ORM\JoinColumn(name="author_id", referencedColumnName="id")
protected $author;
}
BlogBundle \ Entity \ User
use App\UserBundle\Entity\User as BaseUser
@ORM\Entity
@ORM\table(name="app_user")
class User extends BaseUser
{
....
@ORM\OneToMany(targetEntity="App\BlogBundle\Entity\Post", mappedBy="author")
protected $posts;
public function __construct()
{
parent::_construct();
$this->posts = new \Doctrine\Common\Collections\ArrayCollection();
}
....
/* Getters & Setters, nothing that defines @ORM\Column, nothing persisted */
}
これは機能しますが、問題は、プロジェクト内の2つのエンティティを同じテーブルにマッピングしていることです。拡張オブジェクトは、その親から@ORM \ Table(name = "app_user")を取得しないため、BlogBundle \ Entity\Userで定義する必要があります。コントローラからこのオブジェクトへの参照がない場合、データベースにアクセスしません。拡張オブジェクトからは何も永続化されないため、コンソールからデータベーススキーマを更新しようとする場合を除いて、何も壊れません。
一方向の関係を使用できますが、これにより、コントローラー内からデータにアクセスする方法が制限されます。