2016-08-04 98 views
2

是否有可能创建一个关系到泛型表/类与whith教条?学说映射到未知实体

下面是一些代码,使其更容易理解:

// class Log... 

// TODO: 
// It could be useful to have a reference to 
// the element mentioned by the log, the issue is 
// we don't know what kind of entity it is. 

/** 
* @ORM\ManyToOne(targetEntity="???") 
*/ 
private $elementId 

也许不是使用targetEntity我可以只使用一个int是坐落在不明表元素的ID。

+0

您是否尝试过使用'ResolveTargetEntity Listener'? http://symfony.com/doc/current/doctrine/resolve_target_entity.html – malarzm

+0

@malarzm我认为他只是希望能够将他的Logentity与他所有的其他实体绑定在一起。当元数据被缓存时,ResolveTargetEntityListener似乎只解析相关类型一次。 – Alsatian

回答

2

没有内置的可能性了。

我提议让我们周围使用Doctrine Lifecycle Events工作:

  • 创建3个属性:

    /* 
    * @ORM\Column(name="element_class", type="string") 
    */ 
    private $elementClass 
    
    /* 
    * @ORM\Column(name="element_id", type="integer") 
    */ 
    private $elementId 
    
    // Not mapped 
    private $element 
    
    public function setElement($element) 
    { 
        $this->element = $element; 
        $this->elementClass = get_class($element); 
        $this->elementId = $element->getId(); 
    } 
    
    public function getElement() 
    { 
        return $this->element; 
    } 
    
    // You need these for the PostLoad event listener : 
    
    public function hydrateElementPostLoad($element) 
    { 
        $this->element = $element; 
    } 
    
    public function getElementClass() 
    { 
        return $this->elementClass; 
    } 
    
    public function getElementId() 
    { 
        return $this->elementId; 
    } 
    
  • 然后创建一个PostLoadListener能够滋润元素属性:

    namespace AppBundle\EventListener; 
    
    use Doctrine\ORM\Event\LifecycleEventArgs; 
    
    use AppBundle\Entity\Log; 
    
    class PostLoadListener 
    { 
        public function postLoad(LifecycleEventArgs $args) 
        { 
         $entity = $args->getEntity(); 
    
         if($entity instanceOf Log){ 
          $em = $args->getEntityManager(); 
          $entity->hydrateElementPostLoad(
           $this->em->getRepository($entity->getElementClass())->findOneById($entity->getElementId()) 
          ); 
         } 
        } 
    } 
    
  • 并在您的服务中注册此事件s.yml:

    services: 
        places.listener: 
         class: AppBundle\EventListener\PostLoadListener 
         tags: 
          - { name: doctrine.event_listener, event: postLoad } 
    

这也是如何最著名的套件,记录作品(The Gedmo DoctrineExtensions Logger

  • 要检索实体的所有日志,为你的登录实体创建一个存储库方法:

    getLogs($entity) 
    { 
        return $this->_em->findBy(array(
         'element_id'=>$entity->getId(), 
         'element_class'=>get_class($entity) 
        )); 
    } 
    
+0

有一个错字'$ this-> dm-> getRepository' ...它应该是'em'。 我得到'当我尝试更新模式时,没有扩展能够加载“my_app_test.listener”的配置。 MyApp是应用程序的名称,TestBundle是该包的名称。任何建议? – aurelienC

+0

你的意思是“你的监听器必须是服务,而不是配置密钥”? – aurelienC

+0

如果您将服务声明为my_app_test.listener而没有剩下4个空格,则它将被解释为配置密钥。 – Alsatian

2

您正在试图管理一个或多个数据库中的水平,这是一个头痛的实体的一些抽象,

主义已经提出了索姆河的解决方案通过使用继承映射

来管理这种抽象

映射超类是一个抽象或具体的类,为其子类提供持久化的实体状态和映射信息,但它本身不是一个实体。通常,这种映射超类的目的是定义多个实体类共有的状态和映射信息。

有关更多信息,请this