我正在使用bash脚本创建一个简单的项目"从零到CRUD"使用一些工具和Symfony 3 bin / console doctrine:generate:* 它工作正常,但在M:N关联情况下,我无法从反面更新数据。 我在这里阅读了一些答案,我开始进行一些测试,但我感到困惑的是" cascade = {" all"}"选项,' by_reference' =>虚假和其他暗示。 从这个从官方学说文档中获取的基本示例开始,最简单的方法是什么?
/** @Entity */
class User {
// ...
/**
* Many Users have Many Groups.
* @ManyToMany(targetEntity="Group", inversedBy="users")
*/
private $groups;
public function __construct() {
$this->groups = new \Doctrine\Common\Collections\ArrayCollection();
}
// ...
}
/** @Entity */
class Group {
// ...
/**
* Many Groups have Many Users.
* @ManyToMany(targetEntity="User", mappedBy="groups")
*/
private $users;
public function __construct() {
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
// ...
}
答案 0 :(得分:2)
这是Symfony和Doctrine中多对多关系的完整示例。我通常使用yaml而不是注释。因此,如果您想使用注释,则必须使用注释转换代码。
# AppBundle/Entity/User.php
//the id + more fields here if needed
//getters and setters for the other fields
/**
* @var \Doctrine\Common\Collections\Collection
*/
private $groups;
public function __construct()
{
$this->groups = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add group
*
* @param \AppBundle\Entity\Group $group
*
* @return User
*/
public function addGroup(\AppBundle\Entity\Group $group)
{
if ($this->groups->contains($group)) {
return;
}
//those two lines of code are the one you are seeking for, for saving both the owning side and the inverse side
$this->groups[] = $group;
$group->addUser($this);
return $this;
}
/**
* Remove group
*
* @param \AppBundle\Entity\Group $group
*/
public function removeGroup(\AppBundle\Entity\Group $group)
{
if (!$this->groups->contains($group)) {
return;
}
//those are the lines for removing the owning side and the inverse side
$this->groups->removeElement($group);
$group->removeUser($this);
}
/**
* Get groups
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getGroups()
{
return $this->groups;
}
# AppBundle/Resources/config/doctrine/User.orm.yml
AppBundle\Entity\User:
type: entity
table: users
repositoryClass: AppBundle\Repository\UserRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
manyToMany:
groups:
targetEntity: AppBundle\Entity\Group
inversedBy: users
joinTable:
name: groups_users
joinColumns:
user_id:
referencedColumnName: id
nullable: true
inverseJoinColumns:
group_id:
referencedColumnName: id
cascade: ['persist', 'remove']
fetch: EAGER
fields:
# more fields here if needed
lifecycleCallbacks: { }
# AppBundle/Entity/Group.php
//the id + more fields here if needed
//getters and setters for the other fields
/**
* @var \Doctrine\Common\Collections\Collection
*/
private $users;
public function __construct()
{
$this->users = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add user
*
* @param \AppBundle\Entity\User $user
*
* @return Group
*/
public function addUser(\AppBundle\Entity\User $user)
{
if ($this->users->contains($user)) {
return;
}
//these lines saves both the inverse side and the owning side
$this->users[] = $user;
$user->addGroup($this);
return $this;
}
/**
* Remove user
*
* @param \AppBundle\Entity\User $user
*/
public function removeUser(\AppBundle\Entity\User $user)
{
if (!$this->users->contains($user)) {
return;
}
//these lines remove both the inverse side and the owning side
$this->users->removeElement($user);
$user->removeGroup($this);
}
/**
* Get users
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
# AppBundle/Resources/config/doctrine/Group.orm.yml
AppBundle\Entity\Group:
type: entity
table: groups
repositoryClass: AppBundle\Repository\GroupRepository
id:
id:
type: integer
id: true
generator:
strategy: AUTO
manyToMany:
users:
targetEntity: AppBundle\Entity\User
mappedBy: groups
cascade: ['persist']
fetch: EAGER
fields:
# more fields here if needed
lifecycleCallbacks: { }
我希望我没有犯任何错误,因为我在你的身上调整了我的本地Category
- Product
示例。
接下来,您需要在每种表单类型中都有一个字段,以便能够为用户和组的用户选择组。
# AppBundle/Form/UserType.php
$builder
->add('name') // this is a field I used in my local example, you can add yours
->add('groups', EntityType::class, [
'class' => 'AppBundle:Group',
'placeholder' => 'Choose a Group',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('g')
->orderBy('g.name', 'DESC');
},
'choice_label' => 'name',
'multiple'=>true,
'expanded'=>false,
'by_reference' => false,
])
# AppBundle/Form/GroupType.php
$builder
->add('name')
->add('users', EntityType::class, [
'class' => 'AppBundle:User',
'placeholder' => 'Choose User',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.name', 'DESC');
},
'choice_label' => 'name',
'multiple'=>true,
'expanded'=>false,
'by_reference' => false,
])
在更新架构之前,您需要创建两个实体,不带任何映射。然后更新模式,然后继续创建实体之间的多对多关系,并再次更新模式,以应用关系。试一试,让我们知道它是否有效。