2017-11-25 120 views
1

我需要使用Document模型返回完整響應。我有迴應,但缺少一些實體定義的領域。例如,我需要回應「廣告系列」和「模板」屬性 - 但實際上「廣告系列」不存在。控制器不會返回Symfony 2中的OneToMany關係字段

下面是我的控制器和實體。

我有我的控制器,這樣的行動:

/** 
* @REST\View(serializerGroups={"Default", "DocumentDetails"}) 
* @REST\Get("/{id}", requirements={"id" = "\d+"}) 
* @ParamConverter("document", class="AppBundle:Document"); 
*/ 
public function showAction(Request $request, Document $document) 
{ 
    return $document; 
} 

但文檔實體有關係:

/** 
* Document entity 
* 
* @ORM\Entity(repositoryClass="AppBundle\Repository\DocumentRepository") 
* @ORM\Table(name="document") 
* @ORM\HasLifecycleCallbacks() 
* 
* @Serializer\ExclusionPolicy("all") 
*/ 
class Document 
{ 
....... 

/** 
* @var campaign 
* @ORM\ManyToOne(targetEntity="Campaign", inversedBy="documents") 
* @ORM\JoinColumn(name="campaign", referencedColumnName="id") 
* 
* @Serializer\Expose() 
*/ 
protected $campaign; // **THIS FIELD IS ABSENT - WHY !???** 

/** 
* @var DocumentTemplate Szablon dokumentu 
* 
* @ORM\ManyToOne(targetEntity="DocumentTemplate") 
* @ORM\JoinColumn(name="template_id", referencedColumnName="id") 
* 
* @Serializer\Expose() 
*/ 
protected $template; // **THIS PROPERTY IS DISPLAYED** 

....... 

$document->template出現在$文件的響應。但$document->campaign缺席。哪裏不對 ?可能它與serializerGroups有某種關係?謝謝你的幫助。

+1

你確定'campaign'不是null嗎? – PizzaLover

+0

是的,在數據​​庫中它被設置爲與現有Campaign相關的有效ID號碼。 – Lexxusss

+0

你有getter/setters嗎?如果您正在獲取模板而不是Campaign,則代碼中會出現錯誤。 – MEmerson

回答

1

解決!感謝大家的幫助。該問題與JMSSerializer有關。 有需要首先設置串行器配置文件中services.yml

app.serializer.listener.document: 
    class: AppBundle\EventListener\Serializer\DocumentSerializationListener 
    tags: 
     - { name: jms_serializer.event_subscriber } 

然後建立這個監聽器是創建表單子場campaign和插入有活動對象:

<?php 


namespace AppBundle\EventListener\Serializer; 


use AppBundle\Entity\Campaign; 
use AppBundle\Entity\Document; 
use JMS\Serializer\EventDispatcher\EventSubscriberInterface; 
use JMS\Serializer\EventDispatcher\ObjectEvent; 

class DocumentSerializationListener implements EventSubscriberInterface 
{ 
    /** 
    * @param ObjectEvent $event 
    * @return void 
    */ 
    public function onPostSerialize(ObjectEvent $event) 
    { 
     $entity = $event->getObject(); 

     if (!($entity instanceof Document)) { 
      return ; 
     } 

     $groups = $event->getContext()->attributes->get('groups')->getOrElse([]); 

     if (in_array('DocumentDetails', $groups)) { 
      $visitor = $event->getVisitor(); 

      $campaign = $this->getCampaignClone($entity->getCampaign()); 

      if ($visitor->hasData('campaign')) { 
       $visitor->setData('campaign', $campaign); 
      } else { 
       $visitor->addData('campaign', $campaign); 
      } 
     } 
    } 

    /** 
    * @inheritdoc 
    */ 
    public static function getSubscribedEvents() 
    { 
     return [ 
      [ 
       'event' => 'serializer.post_serialize', 
       'class' => 'AppBundle\Entity\Document', 
       'method' => 'onPostSerialize' 
      ] 
     ]; 
    } 

    private function getCampaignClone(Campaign $documentCampaign) 
    { 
     $campaign = new \stdClass(); 
     $campaign->id = $documentCampaign->getId(); 
     $campaign->title = $documentCampaign->getTitle(); 
     $campaign->status = $documentCampaign->getStatus(); 
     $campaign->rows = $documentCampaign->getRows(); 
     $campaign->createdAt = $documentCampaign->getCreatedAt()->format(DATE_W3C); 
     $campaign->updatedAt = $documentCampaign->getUpdated()->format(DATE_W3C); 

     return $campaign; 
    } 
} 

這看起來奇怪我知道 - 但這個唯一的解決方案,我發現強制將實體插入表單請求。