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