我在多对多的关系中遇到了一些麻烦。我有Users
和Assets
。我希望能够将用户分配到资产页面上的资产。
以下代码显示创建/编辑资产时的用户列表,但是对用户复选框所做的更改不会保存,而其余数据会保留。
如果我通过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;
}
答案 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