2016-07-07 120 views
1

我有一个Symfony来创建实体News的新记录。它的一个属性是$newsArticle,它与实体NewsArticle有一对多的关系,并保存新闻记录的翻译。 我的表单应该一次创建一个新的News记录和一个相关的NewsArticle记录(标准语言)。 恕我直言关系与@ORM注释的帮助下正确定义:Symfony Form/Doctrine:保存尚未保留的实体的外键

class News { 
    // ... 

    /** 
    * @ORM\OneToMany(targetEntity="NewsArticle", mappedBy="news", cascade={"persist", "remove"}) 
    */ 
    protected $newsArticle; 

    // ... 

    /** 
    * Add newsArticle 
    * 
    * @param \Acme\Bundle\Entity\NewsArticle $newsArticle 
    * 
    * @return News 
    */ 
    public function addNewsArticle(\Acme\Bundle\Entity\NewsArticle $newsArticle) 
    { 
     $this->newsArticle[] = $newsArticle; 

     return $this; 
    } 
} 


class NewsArticle { 
    // ... 

    /** 
    * @ORM\ManyToOne(targetEntity="News", inversedBy="newsArticle") 
    * @ORM\JoinColumn(name="news_id", referencedColumnName="id") 
    */ 
    private $news; 
} 

问题:发送表格后的新闻和NewsArticle记录被创建,但场news_id不具有价值。

关于这个问题我在Symfony Docs发现(学说:层叠关系和保存“反”面)与一多对许多关系的解决方案的例子:

诀窍是要确保在每个“标签”上设置单个“任务”。 一个简单的方法做,这是一些额外的逻辑添加到addTag(),它 由表单类型,因为by_reference设置为false叫:

// src/AppBundle/Entity/Task.php 

// ... 
public function addTag(Tag $tag) 
{ 
    $tag->addTask($this); 

    $this->tags->add($tag); 
} 

标记内,只要确保你有一个addTask方法:

// src/AppBundle/Entity/Tag.php 

// ... 
public function addTask(Task $task) 
{ 
    if (!$this->tasks->contains($task)) { 
     $this->tasks->add($task); 
    } 
} 

如果你有一个一对多的关系,那么解决办法是 类似,不同之处在于,你可以简单地从里面addTag调用setTask。

所以我延长我的这样的代码:

public function addNewsArticle(\Acme\Bundle\Entity\NewsArticle $newsArticle) 
{ 
    $newsArticle->setNews($this); 
    $this->newsArticle[] = $newsArticle; 

    return $this; 
} 

...不幸的是这将导致一个错误消息:

实体传递到选择现场必须加以管理。可能坚持 他们在实体经理?

我不知道如何解决这个问题。任何人都可以给我一个提示吗?或者甚至是创建尚未持续的相关实体的更好解决方案?

在此先感谢!

编辑:NewsController(节选)

public function addAction(Request $request) { 

    $article = new NewsArticle(); 
    $article->setLanguageId($lang); 

    $news = new News(); 
    $news->setPublic(0); 
    $news->setDeleted(0); 
    $news->setIdent($hash); 
    $news->setRank($rank); 
    $news->addNewsArticle($article); 

    $form = $this->createForm(NewsType::class, $news, ['languageId' => $lang]); 
    $form->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 

     $em = $this->getDoctrine()->getManager(); 
     $em->persist($news); 
     $em->flush(); 

     $this->addFlash(
      'success', 
      'Your changes were saved!' 
     ); 

    } 

    return $this->render('AcmeBundle:News:add.html.twig', array(
     'form' => $form->createView(), 
     'news' => $news, 
    )); 
} 
+0

只是想补充一点,如果您在同一个请求中对其进行操作,则不必刷新以获取标识。你需要的唯一东西(至少从我的经验中使用Symfony和Mongo)是坚持的;那时你可以开始使用它作为参考。直到您坚持使用,该ID将不可用 – Simon

回答

0

似乎从来就解决了这个问题,并it's不是在代码从来就贴在我的问题,但在FormType代码。

+0

您可以发布代码吗?这将有助于其他人解决类似的问题。 – Tek

0

它会更好,如果你将长期存在的所有实体:

$em = $this->getDoctrine()->getManager(); 
$em->persist([$news, $article]); 
$em->flush(); 

祝你好运!