Sonata Admin Bundle 和 Doctrine 问题:如何从反面更新实体?

Posted

技术标签:

【中文标题】Sonata Admin Bundle 和 Doctrine 问题:如何从反面更新实体?【英文标题】:Sonata Admin Bundle and Doctrine issue: how to update an entity from inversed side? 【发布时间】:2012-09-03 11:55:47 【问题描述】:

我有两个实体之间的多对多关系。我们称它们为UserGroup

我决定在创建/更新界面上,因为它们可以关联,您可以直接关联来自组表单的用户或来自用户表单的组。请注意,关系的拥有方是User

现在问题来了。如果我从用户表单界面关联组,一切都很好并且工作完美(教义寻找拥有方的变化)。如果我尝试从组表单界面关联User,则没有任何效果。

显然我完全知道我必须将用户“添加”到组对象中,并将组 (this) 添加到我从表单传递的每个用户对象中。实际上这是我在Group实体中的sn-p代码

public function setUsers(\Doctrine\Common\Collections\ArrayCollection $utente)

    /* snippet of code for removing old association , didn't reported */

    foreach($utente as $u)
        $this->users[] = $u;
        $u->addGroups($this);
    

从这个sn-p进入创造形式,做好他的工作。进入更新,它没有。 所以我想这一定是奏鸣曲的问题,或者是我目前错过的东西。

有什么建议吗?

更新

在花了一些时间了解这里发生了什么之后,我发现setUser() 没有被调用到更新操作中(读作提交构建在现有实体上的表单)。所以我的代码只有在我创建新条目时才会运行(我仍然没有解决方案)

【问题讨论】:

【参考方案1】:

我刚刚了解了如何更新实体。 我想这是与 Symfony2 相关的行为,而不是 Sonata Admin 的行为。

简而言之,您必须告诉 Symfony2 调用您要更新的对象的 setter。

用于该用途:

by_reference => false

在 Sonata Admin Bundle 案例中:

$formMapper
            ->add('nome')
            ->add('canali', 'sonata_type_model', array('required' => false))
            ->add('utenti', 'sonata_type_model', array('required' => false,
                                                       'by_reference' => false))
        ;

在纯 Symfony2 形式的情况下:

->add('utenti', 'collection', array(
                'type' => new User(),
                'allow_add' => true,
                'allow_delete' => true,
                'prototype' => true,
                'by_reference' => false,
            ))
        ;

【讨论】:

【参考方案2】:

不清楚你的意思是更新它不能很好地工作。根据您的代码,我假设它会在用户和组之间添加新的关系,但不会删除旧的。

public function setUsers(\Doctrine\Common\Collections\ArrayCollection $utente)

    // to synch internal and external collections, remove relation between users and groups if user is not in the new collection
    foreach ($this->users as $u) 
        if (!$utente->contains($u)) 
            // add this function to user object, it's trivial, just remove give group from internal groups collection
            $u->removeGroup($this); 
        
    
    foreach ($utente as $u) 
        if (!$this->users->contains($u)) 
            $this->users[] = $u;
            $u->addGroups($this);
        
    

【讨论】:

是的,我错过了仅添加新用户的控件。但是您完全错过了这个问题:setUsers 似乎不适用于更新操作【参考方案3】:

尝试将以下内容添加到您的管理类

public function prePersist($group)

    $group->setUsers($group->getUsers());
    parent::prePersist($testQuestion);


public function preUpdate($group)

    $group->setUsers($group->getUsers());
    parent::preUpdate($testQuestion);

【讨论】:

以上是关于Sonata Admin Bundle 和 Doctrine 问题:如何从反面更新实体?的主要内容,如果未能解决你的问题,请参考以下文章

Sonata Media Bundle 与 Sonata Admin Bundle 3.0(或 2.4)

Sonata admin-bundle - 没有注销导航栏

Sonata Admin Bundle 中的标签

Sonata Admin Bundle - 自定义模板

sonata-project/user-bundle dev-master 与 sonata-project/doctrine-orm-admin-bundle 冲突

CKEditorType 在 symfony sonata admin 中显示文本区域