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

时间:2012-02-01 19:36:03

标签: forms symfony many-to-many doctrine-orm

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

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

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

用户

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

资产

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

AssetType

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

    return $form;
}

5 个答案:

答案 0 :(得分:31)

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

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;

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

AssetType:
->add('users', null, array('expanded' => "true", "multiple" => "true"))

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

感谢您的建议!!!

答案 1 :(得分:17)

  

不完全确定为什么我需要有反转的和   关于资产与用户的JoinTable信息,但它   似乎现在正在工作!

你的改变被忽略的原因是,学说只保留了关系所有者方面的改变(如@Florian所说)。

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

答案 2 :(得分:13)

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

问题在于,当您保存表单时,symfony实际上是这样做的:

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

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

你真正需要做的就是这样称呼:

$asset->addUser($user)

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

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);
}

因此,为了使symfony使用$asset->addUser()方法,您应该设置

<强> 'by_reference' => false

users表单的AssetType字段上

有关此设置的详情,请http://symfony.com/doc/current/reference/forms/types/form.html#by-reference

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

答案 3 :(得分:4)

首先,您应该在注释中删除反斜杠前缀(请参阅注意here)。

您需要使用实体字段类型:

$builder->add('users', 'entity', array(
    'class' => 'AdaptiveUserBundle:User',
    'expanded' => true,
    'multiple' => true,
    'query_builder' => function(EntityRepository $er) {
        return $er->createQueryBuilder('u')
            ->orderBy('u.username', 'ASC');
    },
));

答案 4 :(得分:0)

您需要在表单中使用“收集”字段类型。

$builder->add('users', 'collection', array(
    'type' => new UserType(),
    'prototype' => true,
    'allow_add' => true,
    'allow_delete' => true
));

您需要首先创建UserType()表单。

以下是您需要的所有信息,包括代码示例:

http://symfony.com/doc/current/cookbook/form/form_collections.html

http://symfony.com/doc/current/reference/forms/types/collection.html