当前位置: 首页 > 知识库问答 >
问题:

Symfony2嵌套形式和ManyTo许多关系

葛骏
2023-03-14

我正在尝试处理一个对我来说相当复杂的表格...

我们有收藏,其中包含书籍(OneTo多国),文章(OneTo多国)及其作者(ManyTo多国)。

用户可以编辑一本书:他可以添加或删除一篇文章,还可以为每篇文章添加或删除一些作者。有嵌套表单:book

实体描述看起来很好,数据库是由控制台生成的,看起来是一致的。

如果我不必与使用图书版表单的作者打交道,这就很好了。如果作者存在,我有一个重复条目错误。如果作者是新的,我有一个“显式持久化新实体或在关系上配置级联持久化操作”错误。

代码如下:

public function onSuccess(Book $book)
{   
    $this->em->persist($book);

    foreach($book->getArticles() as $article)  
    {
        $article->setUrlname($this->mu->generateUrlname($article->getName()));
        $article->setBook($book);

        // Saving (and creating) the authors of the book
        foreach ($this->collectionWithAuthors->getAuthors() as $existAuthor){      
            foreach($article->getAuthors() as $author) {                        
                $authorUrlname=$this->mu->generateUrlname($author->getFirstname().' '.$author->getLastname());
                if ( $existAuthor->getUrlname() ==  $authorUrlname) { // The author is existing
                    $article->addAuthor($existAuthor);
                    $this->em->persist($existAuthor);
                }else{                                                // New Author
                    $newAuthor = new Author();                                
                    $newAuthor->setCollection($this->collectionWithBaseArticles);
                    $newAuthor->setLastname($author->getLastname());
                    $newAuthor->setFirstname($author->getFirstname());
                    $newAuthor->setUrlname($authorUrlname);
                    $this->em->persist($newAuthor);
                    $article->addAuthor($newAuthor);                          
                }
            }
        }
        $this->em->persist($article);

    }
    $this->em->flush();

}

我不知道如何使用级联。但是$文章-

文章实体摘录

/**
* @ORM\ManyToMany(targetEntity="bnd\myBundle\Entity\Author", mappedBy="articles")
*/
private $authors;

/**
 * Add authors
 *
 * @param bnd\myBundle\Entity\Author $authors
 * @return Article
 */

public function addAuthor(\bnd\myBundle\Entity\Author $authors)
{
    $this->authors[] = $authors;
    $authors->addArticle($this);
}

共有1个答案

祁柏
2023-03-14

foreach语句中的逻辑错误。假设我们有下一位作者:

  • 持久化作者(collectionWithAuthors):
    • 约翰
    • 埃里克
    • Ada

    因此,对于每个现有作者(John和Eric),脚本都会循环到新作者:

    foreach ([John, Eric] as $author) {
        foreach([Ada, Eric] as $newAuthor) {
            // John author: the script persist Ada(right) and Eric(wrong) as new authors
            // Eric author: the script persist Ada(wrong), but not Eric(right)
        }
    }
    

    解决方案是用现有作者替换文章作者(如果有类似的)

    foreach ($article->getAuthors() as $key => $articleAuthor) {
        $authorUrlname=$this->mu->generateUrlname($articleAuthor->getFirstname().' '.$articleAuthor->getLastname());
        $foundAuthor = false;
        // Compare article author with each existing author
        foreach ($this->collectionWithAuthors->getAuthors() as $existAuthor) { 
            if ($existAuthor->getUrlname() ==  $authorUrlname) {
                $foundAuthor = true;
                break; // It has found similar author no need to look further
            }
        }
    
        // Use $existAuthor as found one, otherwise use $articleAuthor
        if ($foundAuthor) {
            $article->removeAuthor($articleAuthor); // Remove submitted author, so he wont be persisted to database
            $article->addAuthor($existAuthor);
        } else {
            // Here you dont need to create new author                          
            $articleAuthor->setCollection($this->collectionWithBaseArticles);
            $articleAuthor->setUrlname($authorUrlname);
        }
    
        ...
    }
    
    $this->_em->persist($article);
    

    您已经注意到,我从循环中删除了任何author persistent,为了持久化这些author,最好在Article实体类的$authors注释中设置cascade={'persistent}

    /**
     * @ORM\ManyToMany(targetEntity="Author", cascade={"persist"})
     * @ORM\JoinTable(...)
     */
    protected $authors;
    

    UPD:

    关于cascade persistent,我忘了提一件事。要保持文章和作者之间的关系,还必须将关系添加到作者实体。编辑文章实体中的addAuthor()方法,如下所示:

    public function addAuthor(Author $author)
    {
        // Only add author relation if the article does not have it already
        if (!$this->authors->contains($author)) {
            $this->authors[] = $author;
            $author->addArticle($this);
        }
    }
    

    此外,为构造函数中的实体集合定义默认值也是一种很好的做法:

    use Doctrine\Common\Collections\ArrayCollection;
    
    // ...
    
    public function __construct()
    {
        $this->authors = new ArrayCollection();
    }
    

 类似资料:
  • 只使用一个集合很好,但是我需要编辑外部窗体的原型,所以它为每一行呈现内部窗体的原型。 你知道我该怎么做吗?还有什么是最好的储蓄方式 编辑:现在我正在尝试呈现嵌套窗体的原型: 促销特征选择类型 第一级原型,工作很好。

  • 我在连接Laravel中的数据库模型时遇到问题。 现在,我想把它们连接起来,就像,每个用户可以有多个公司,每个公司都有自己的company_details。 我的用户。php模型如下所示: 如何从company_details表中获取值?

  • 问题内容: 具有角形的这种普通(名称属性由服务器要求)形式,无法弄清楚如何使验证有效。我应该在ng-show =“ TODO”中添加什么 http://jsfiddle.net/Xk3VB/7/ ps:这只是一种形式,更复杂 谢谢 问题答案: AngularJS依靠输入名称来暴露验证错误。 不幸的是,到目前为止,不可能(不使用自定义指令)动态生成输入的名称。确实,检查输入文档,我们可以看到name

  • 我在当前项目中使用Sass(.scss)。 以下示例: HTML SCSS 这个很管用。 我可以处理多个类,同时使用嵌套样式。 在上面的示例中,我讨论了以下内容: CSS 在这种情况下,所有通常为,但为蓝色。 我如何在中与Sass嵌套?

  • 问题内容: 我在laravel中很难建立起非常嵌套的关系。 所需的行为如下, 我通过ID选择一个事件,我想查看哪些人已订阅该事件。 现在的问题是事件和人员之间有一些表格。 这是有效的查询! 事件模型 城市模型 公司模式 人物模型 我尝试过的 和 还有很多其他可能性,我真的很坚持。在laravel中实现这种嵌套关系链接如此困难吗? 谢谢! 问题答案: 如果只想从表中选择某些字段,请使用以下命令:

  • 在之前,创建一个有依赖其他模型的模型的时候,我们需要提前把依赖的模型给建立好,这样就非常麻烦,是不是有那么一种方法,在一个 create 里面把其他的依赖模型一起新建出来呢? 这一小节就来解决这个问题。这其中有一个坑(关于命名),让我调试的头皮发麻。 Book 与 User 的 belongs 关系 1. 保存关系 来到 book.ts , 首先保存一下 this.belongsTo 的返回值,在