关联实体记录问题

时间:2016-10-20 18:10:47

标签: php symfony doctrine-orm

我在网络应用中完成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;
}

1 个答案:

答案 0 :(得分:0)

我对映射信息的建议很少。

除非您在实体经理cascade={"all"}上使用createeditdelete个子实体,否则您不应该flush()

其次,为什么需要在映射的两端定义@ORM\JoinTable信息?

您应该只从mapped-by方面定义它。在您的示例中,您应该只有@ORM\JoinTable实体Contact,因为它有mapped-by个信息。 Documents here

虽然我不确定这会解决您的问题,但您应始终拥有正确的映射信息。

希望这有帮助!