我在网络应用中完成ManyToMany关系时遇到问题。
我们有实体联系和标签。多对多关系由以下代码编写:
联系
/**
* Contact
*
* @ORM\Table(name="contacts")
* @ORM\Entity(repositoryClass="Admin\MainBundle\Repository\ContactRepository")
*/
class Contact
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\ManyToMany(targetEntity="Tag", inversedBy="contacts", cascade={"all"})
* @ORM\JoinTable(name="contact_tag_relation",
* joinColumns={@ORM\JoinColumn(name="contact_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
* )
*/
private $tags;
标签
/**
* Tag
*
* @ORM\Table(name="tags")
* @ORM\Entity(repositoryClass="Admin\MainBundle\Repository\TagRepository")
*/
class Tag
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var ArrayCollection
* @ORM\ManyToMany(targetEntity="Admin\MainBundle\Entity\Contact", mappedBy="tags", cascade={"all"})
* @ORM\JoinTable(name="contact_tag_relation",
* joinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="contact_id", referencedColumnName="id")}
* )
*/
private $contacts;
Controller的请求处理程序。
public function editAction(Request $request, Tag $tag, Contact $contact = null)
{
$deleteForm = $this->createDeleteForm($tag);
$editForm = $this->createForm('Admin\MainBundle\Form\TagType', $tag);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
return $this->redirectToRoute('tags_edit', array('id' => $tag->getId()));
}
return $this->render('AdminMainBundle:Tag:edit.html.twig', array(
'tag' => $tag,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
TagType方法
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('contacts');
}
GET请求到位置以进行编辑标记后,服务器返回输入字段,用于更改标记的标题,其中包含当前值和多选输入字段以及当前与标记相关的标记联系人。 当我在multiselect字段上进行更改并提交时,更改不会记录。
这可能有什么问题?如何解决这个问题并保持代码清洁?
contacts属性在控制器的方法中表示为persistentcollection类型,并标记为脏。
UDATE 1:
标签(ge& se)tters:
/**
* Add contact
*
* @param \Admin\MainBundle\Entity\Contact $contact
*
* @return Tag
*/
public function addContact(\Admin\MainBundle\Entity\Contact $contact)
{
$this->contacts[] = $contact;
return $this;
}
/**
* Remove contact
*
* @param \Admin\MainBundle\Entity\Contact $contact
*/
public function removeContact(\Admin\MainBundle\Entity\Contact $contact)
{
$this->contacts->removeElement($contact);
}
/**
* Get contacts
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getContacts()
{
return $this->contacts;
}
联系人(ge& se):
/**
* Add tag
*
* @param \Admin\MainBundle\Entity\Tag $tag
*
* @return Contact
*/
public function addTag(\Admin\MainBundle\Entity\Tag $tag)
{
$this->tags[] = $tag;
return $this;
}
/**
* Remove tag
*
* @param \Admin\MainBundle\Entity\Tag $tag
*/
public function removeTag(\Admin\MainBundle\Entity\Tag $tag)
{
$this->tags->removeElement($tag);
}
/**
* Get tags
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
答案 0 :(得分:0)
我对映射信息的建议很少。
除非您在实体经理cascade={"all"}
上使用create
或edit
或delete
个子实体,否则您不应该flush()
。
其次,为什么需要在映射的两端定义@ORM\JoinTable
信息?
您应该只从mapped-by
方面定义它。在您的示例中,您应该只有@ORM\JoinTable
实体Contact
,因为它有mapped-by
个信息。 Documents here
虽然我不确定这会解决您的问题,但您应始终拥有正确的映射信息。
希望这有帮助!