Подтвердить что ты не робот

Расширение объектов в Symfony2 с помощью Doctrine2

У меня возникли проблемы с поиском способа надлежащего расширения Entity через пакеты в Symfony2 с использованием Doctrine2 в качестве ORM.

В настоящее время существует три метода, которые я обнаружил для расширения объектов в Symfony2 с использованием Doctrine2 в качестве ORM. Mapped Superclass, Single Table Inheritance и Class Table Inheritance. Ничто из этого не работает для того, что я ищу.

У меня есть два пакета: UserBundle и BlogBundle. Я хочу иметь возможность использовать UserBundle в проектах, которые не имеют BlogBundle, но BlogBundle всегда будет использоваться в проектах, у которых есть User Bundle. Это нормально, если у BlogBundle есть зависимости от UserBundle, но не наоборот.

У меня есть два объекта: BlogBundle\Entity\Post и UserBundle\Entity\User

Отношения: Между пользователями и сообщениями в блогах должно быть отношение "Один ко многим". Это достигается с помощью свойства Author_ID (столбец) объекта BlogBundle\Entity\Post (таблица), который сопоставляется с UserBundle\Entity\User.id

Проблема: Я могу вызвать объект UserBundle\Entity\User непосредственно из BlogBundle и добиться того, что я ищу, используя Uni-Directional mapping. Это не позволяет мне получать доступ ко всем сообщениям пользователя из объекта пользователя. Я могу получить доступ к данным через пользовательские запросы, но это не так чисто, как доступ к сообщениям пользователя через пользовательский объект.

То, что я хотел бы сделать, это расширить объект UserBundle\Entity\User из BlogBundle и добавить методы и свойства к этому объекту, которые устанавливают отображение One to Many, используемое в BlogBundle. Ничто из этого не сохраняется, оно просто определяет взаимосвязь и позволяет мне логически получать доступ ко всем сообщениям, созданным пользователем в приложении, которое реализует как BlogBundle, так и UserBundle, добавляя необходимые функции к объекту User в блоге (таким образом избегая зависимости из UserBundle в BlogBundle).

Когда я создаю объект BlogBundle\Entity\User и расширяю UserBundle\Entity\User, я должен объявить @ORM\Table (name= "usertablename" ). Если я этого не сделаю, любая попытка доступа к объекту BlogBundle\Entity\User не сможет получить доступ к базе данных. Поскольку ни одно из добавлений в расширенном объекте не сохраняется, это отлично работает через узлы. Проблема в том, что когда я называю "php app/console doctrine: schema: update -force", возникает конфликт, поскольку два объекта пытаются сопоставить и создать одну и ту же таблицу. Я попытался использовать функцию ResolveTargetEntityListener, которая была недавно реализована, но это, наряду с Mapped Superclas, STI и CTI, все заставляют зависеть от BlogBundle от UserBundle.

Ниже приведены мои объекты, которые помогут проиллюстрировать мою настройку. Они были сокращены для ясности. Я понимаю, что некоторые из семантики неверны, но они предназначены для передачи идей и конфигурации.

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 */
}

Это работает, но проблема в том, что я сопоставляю два объекта в проекте в одну и ту же таблицу. Расширенный объект не захватывает @ORM\Table (name= "app_user" ) из его родителя, поэтому он должен быть определен в BlogBundle\Entity\User. Если никакая ссылка на этот объект с контроллера не будет обращаться к базе данных. Поскольку из расширенного объекта ничего не сохраняется, ничего не происходит, кроме тех случаев, когда я пытаюсь обновить схему базы данных с консоли.

Я могу использовать однонаправленную связь, но это ограничивает доступ к данным из контроллера.

4b9b3361

Ответ 1

Вы можете видеть в этой ссылке, чтобы узнать о наследовании: http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance

Вы должны объявить в UserBundle\Entity\User:

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"baseuser" = "UserBundle\Entity\User", "blogUser" = "BlogBundle\Entity\User"})
 */
class User implements UserInterface
{
    ...
}

И BlogBundle\Entity\User

use App\UserBundle\Entity\User as BaseUser;
/**
 * @ORM\Entity
 */
class User extends BaseUser
{
    ....
}

Гудлак!

Ответ 2

Я думаю, вы могли бы найти этот Bundle интересным:

https://github.com/mmoreram/SimpleDoctrineMapping

Он позволяет вам определять по параметрам, какие файлы сопоставляют ваши объекты, позволяя переопределить каждую сущность ваших общих пакетов.

Например:

parameters:

    #
    # Mapping information
    #
    test_bundle.entity.user.class: "TestBundle\Entity\User"
    test_bundle.entity.user.mapping_file_path: "@TestBundle/Mapping/Class.orm.yml"
    test_bundle.entity.user.entity_manager: default
    test_bundle.entity.user.enable: true

Единственное, что я вижу, это то, что вы должны определить все следующие сущности одинаково, потому что вы отключили auto_mapping...