Symfony2 Doctrine2多对多形式不保存实体

Sha*_*rop 21 forms many-to-many symfony doctrine-orm

我与多对多的关系遇到了一些麻烦.我有UsersAssets.我希望能够将用户分配到资产页面上的资产.

下面的代码显示创建/编辑资产时的用户列表,但是对用户复选框所做的更改不会保存,而其余数据会保留.

如果我通过mysql客户端向users_assets添加条目,则这些更改将显示在资产列表中.

用户

class User extends BaseUser
{
    /**
     * @ORM\ManyToMany(targetEntity="Asset", inversedBy="users")
     */
    private $assets;
}
Run Code Online (Sandbox Code Playgroud)

财富

class Asset
{
    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="assets")
     */
    private $users;
}
Run Code Online (Sandbox Code Playgroud)

AssetType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $form = $builder
        ->add('users', null, array(
            'expanded' => true,
            'multiple' => true
        ))
        ->getForm();

    return $form;
}
Run Code Online (Sandbox Code Playgroud)

Sha*_*rop 32

出于某种原因,我不得不切换学说映射以使其工作:

Asset:
 /**
 * @ORM\ManyToMany(targetEntity="Adaptive\UserBundle\Entity\User", inversedBy="assets")
 * @ORM\JoinTable(name="user_assets")
 */
private $users;

User:
 /**
 * @ORM\ManyToMany(targetEntity="Splash\SiteBundle\Entity\Asset", mappedBy="users")
 */
private $assets;
Run Code Online (Sandbox Code Playgroud)

现在,当我保存资产时,它会保存与之关联的用户.我不需要定义builder-> add作为实体或集合.我只是将它传递给null并使用映射信息填写实体信息:

AssetType:
->add('users', null, array('expanded' => "true", "multiple" => "true"))
Run Code Online (Sandbox Code Playgroud)

不完全确定为什么我需要在Asset vs The User上使用inversedBy和JoinTable信息,但它现在似乎正在运行!

谢谢你的建议!!!


nai*_*rch 17

不完全确定为什么我需要在Asset vs The User上使用inversedBy和JoinTable信息,但它现在似乎正在运行!

你的改变被忽略的原因是,学说只能通过关系的拥有方来保持变化(比如@Florian所说).

这是Doctrine文档的链接,解释了这种行为:http://docs.doctrine-project.org/en/latest/reference/unitofwork-associations.html


Pav*_*nin 14

很奇怪我在2016年面临同样的问题,但仍然很难找到解决方案.我将分享给未来的googlers:

问题是当你保存表单时symfony本质上做的是:

$asset->getUsers()->add($user)

而且因为你处于关系的反面,它不会持续你的改变.

你真正需要的是这样做,它称之为:

$asset->addUser($user)

其中addUser()在Asset实体上以下列方式定义:

public function addUser(User $user) 
{
    //add to the inverse side
    $this->users->add($user);

    //add on the owning side (only this is persisted)
    $user->addAsset($this); //$user->assets->add($asset);
}
Run Code Online (Sandbox Code Playgroud)

所以为了让symfony使用那个$asset->addUser()方法,你应该设置

'by_reference' => false

在你的users领域的AssetType形式.

有关此设置的更多信息,请访问http://symfony.com/doc/current/reference/forms/types/form.html#by-reference

请记住,您还需要以removeUser()相同的方式定义方法(以便它从拥有关系中删除实体)