2012-10-09 22 views
13

Tengo problemas para encontrar una manera de extender apropiadamente una entidad a través de paquetes en Symfony2 usando Doctrine2 como ORM.Entidades extendidas en Symfony2 con Doctrine2

Actualmente, hay tres métodos que he encontrado para extender entidades en Symfony2 usando Doctrine2 como ORM. Mapped Superclass, Single Table Inheritance y Class Table Inheritance. Ninguno de estos funciona para lo que estoy buscando hacer.

Tengo dos paquetes: UserBundle y BlogBundle. Quiero poder usar el UserBundle en proyectos que no tienen BlogBundle, pero el BlogBundle siempre se usará en proyectos que tengan User Bundle. Está bien si el BlogBundle tiene dependencias en el UserBundle, pero no al revés.

que tienen dos entidades: BlogBundle \ Entidad \ postales y de UserBundle \ Entidad \ Usuario

Relación: Es necesario que haya un uno a muchos relación entre los usuarios y las publicaciones de blog. Esto se logra a través de una propiedad author_id (columna) en el objeto BlogBundle \ Entidad \ Post (tabla) que se asigna a UserBundle \ Entidad \ User.id

El problema: puedo llamar a la UserBundle \ Entidad \ Entidad de usuario directamente desde BlogBundle y lograr lo que estoy buscando usando un mapeo Unidireccional. Esto no me permite acceder a todas las publicaciones de un usuario desde dentro de un objeto Usuario. Puedo acceder a los datos a través de consultas personalizadas, pero esto no es tan limpio como acceder a las publicaciones de un usuario a través del objeto de usuario.

Lo que me gustaría hacer es extender el objeto UserBundle \ Entity \ User desde dentro del BlogBundle, y agregar los métodos y propiedades a este objeto que establecen el mapeo One to Many utilizado en el BlogBundle. Nada de esto persiste, simplemente define la relación y me permite acceder lógicamente a todas las publicaciones creadas por un usuario en una aplicación que implementa tanto el BlogBundle como el UserBundle agregando la funcionalidad necesaria al objeto User dentro del paquete del blog (evitando así una dependencia) del UserBundle al BlogBundle).

Cuando creo un objeto BlogBundle \ Entity \ User y extiendo UserBundle \ Entity \ User, debo declarar @ORM \ Table (name = "usertablename"). Si no lo hago, cualquier intento de acceder al objeto BlogBundle \ Entity \ User no podrá acceder a la base de datos. Como ninguna de las adiciones en el objeto extendido persiste, funciona bien en los paquetes. El problema con esto es cuando llamo "php app/console doctrine: schema: update --force", hay un conflicto ya que dos entidades intentan mapear a & crean la misma tabla. He intentado utilizar la característica ResolveTargetEntityListener que se implementó recientemente, pero esto, junto con Mapped Superclas, STI y CTI obligan a una dependencia del BlogBundle del UserBundle.

A continuación se presentan mis objetos para ayudar a ilustrar mi configuración. Se han abreviado para mayor claridad. Me doy cuenta de que algunas de las semánticas no son correctas, pero están destinadas a comunicar la configuración de las ideas &.

UserBundle \ Entidad \ Usuario

@ORM\Table(name="app_user") 
@ORM\Entity 
class User implements UserInterface 
{ 
    ... 
} 

BlogBundle \ Entidad \ Mensaje

@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 \ Entidad \ Usuario

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

Esto funciona, pero el problema es que soy mapeo de dos entidades en el proyecto a la misma tabla. El objeto extendido no toma @ORM \ Table (name = "app_user") de su padre, por lo que debe definirse en BlogBundle \ Entity \ User. Si no, ninguna referencia a este objeto desde un controlador no accederá a la base de datos. Como no se conserva nada del objeto extendido, nada se rompe, excepto cuando trato de actualizar el esquema de la base de datos desde la consola.

Puedo usar una relación unidireccional, pero esto limita la forma en que puedo acceder a los datos desde dentro de un controlador.

+0

Sé que esto es una pregunta muy antigua ; pero alguna vez lo resolviste? Estoy enfrentando los mismos problemas y estoy luchando por encontrar cualquier solución que funcione. – bigstylee

Respuesta

6

Se puede ver en este enlace para saber acerca de la herencia: http://docs.doctrine-project.org/en/latest/reference/inheritance-mapping.html#single-table-inheritance

Debe declarar en UserBundle \ Entidad \ Usuario:

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

Y BlogBundle \ Entidad \ Usuario

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

¡Buena suerte!

+1

No creo que esta sea una solución satisfactoria, ya que hay una referencia del UserBundle al BlogBundle en '@ DiscriminatorMap'. Me interesaría una solución donde UserBundle no tenga referencias/dependencias en el BlogBundle en absoluto. – aimfeld

0

Creo que se podría encontrar este paquete interesante:

https://github.com/mmoreram/SimpleDoctrineMapping

Se le permite definir los parámetros por lo que los archivos están trazando sus entidades, lo que permite anular cualquier entidad de sus paquetes genéricos.

Por ejemplo:

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 

La única contraindicación que veo es que usted tiene que definir todas las siguientes entidades de la misma manera que causa auto_mapping discapacitados ...

Cuestiones relacionadas