Forms Symfony2 Doctrine2多对多表单不保存实体

Forms Symfony2 Doctrine2多对多表单不保存实体,forms,symfony,many-to-many,doctrine-orm,Forms,Symfony,Many To Many,Doctrine Orm,我在多对多关系中遇到了一些麻烦。我有用户和资产。我希望能够将用户分配到资产页面上的资产 下面的代码显示了创建/编辑资产时的用户列表,但是对用户复选框所做的更改不会保存,而其余数据会保留 如果我通过mysql客户端向users\u资产添加一个条目,这些更改将显示在资产列表中 用户 class User extends BaseUser { /** * @ORM\ManyToMany(targetEntity="Asset", inversedBy="users") */

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

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

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

用户

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

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

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

    return $form;
}

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

$builder->add('users', 'collection', array(
    'type' => new UserType(),
    'prototype' => true,
    'allow_add' => true,
    'allow_delete' => true
));
显然,首先需要创建
UserType()
表单

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


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

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


出于某种原因,我不得不切换条令映射以使其正常工作:

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"))
不太清楚为什么我需要关于资产和用户的inversedBy和JoinTable信息,但它现在似乎正在工作

谢谢你的建议

不太清楚为什么我需要倒过来 资产与用户的可接合信息,但 现在好像在工作

你的改变被忽略的原因是,教义只坚持关系的拥有方的改变(如@Florian所说)


这是理论文件的链接,其中解释了这种行为:

奇怪得很,我在2016年遇到了同样的问题,仍然很难找到解决方案。我将与未来的谷歌分享:

问题在于,symfony在保存表单时的基本功能是:

$asset->getUsers()->添加($user)

因为你处于关系的反面,所以你的改变不会持久

您真正需要的是使其称之为:

$asset->addUser($user)

其中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
表单

有关此设置的更多信息,请参见此处


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

我认为通过传递null,它将假定这是通过我的原则映射得到的类型。我有一个类似的设置,在资产上使用类别,效果非常好。这是我必须填充类别集合的代码:->add('categories',null,array('expanded'=>“true”,“multiple”=>“true”))。。。此外,我不需要为资产中的用户添加crud功能,而只需要能够将当前用户分配给该资产。doctrine的from扩展添加了一个基于元数据的猜测器。如果已正确定义多个关联,则类型猜测器会将字段配置为
集合
。正确地说,我的意思是,在您的情况下,关联的所有者必须是
资产
,这就是您必须反转映射的原因。
EntityType
+
扩展
+
多个
有什么问题?我也有类似的问题。给其他人的建议:确保你所有的单数/复数都是它们应该是的,如果你的任何一个实体都有一个多术语名称(例如,
CoolDude
),你可能会受益于知道默认原则是假设你的表名只是它的小写版本,例如,
CoolDude
。如果它真的很酷,我想你必须明确地设置它。你可以在条令文件中看到。问题是当你想在反面有一个类似的形式时:它不起作用。@slaapwagen同样的问题在这里。相反的一面不行。你已经找到这个问题的解决方案了吗?这应该是公认的答案。我想知道,在做一些复古的帖子时,为什么没有人写这篇文章,最后却带着你的来了。很好。资产在这里是拥有方,因此这与@Trix冲突谢谢,我刚刚再次检查了它,确实存在用户/资产混淆。我做了一个编辑-解决方案仍然是一样的,我只调整了变量名以保持一致。您不应该将
null
更改为
EntityType
?你说空是什么意思?!
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);
}