如何在连接用户之后,按照实体之间的ManyToMany关系将默认值设置为symfony表单字段(用户字段)

时间:2015-09-22 09:44:25

标签: forms symfony many-to-many twig fosuserbundle

在我的symfony 2.7应用程序中,我有基于FOSUserBundle的用户实体。必须连接用户才能访问addAction()表单。

我的用户实体与另一个名为parc的实体相关联。这是我的两个实体的代码。

Users.php

class Users extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    public function __construct()
    {
        parent::__construct();
        $this->parcs = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Parcs", inversedBy="users")
     * @ORM\JoinTable(name="users_parcs",
     *   joinColumns={
     *     @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="parc_id", referencedColumnName="id")
     *   }
     * )
     */
    private $parcs;

    /**
     * Get parcs
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getParcs()
    {
        return $this->parcs;
    }

    /**
     * Set parcs
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function setParcs($parcs)
    {
        return $this->parcs;
    }

Parcs.php

class Parcs
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var \Doctrine\Common\Collections\Collection
     *
     * @ORM\ManyToMany(targetEntity="Users", mappedBy="parcs")
     */
    private $users;

    public function __construct()
    {
      $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

//rest of my entity attributes, object, properties etc

// getters and setters

    /**
     * Get users
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getUsers()
    {
        return $this->users;
    }

    /**
     * Set users
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function setUsers($users)
    {
        return $this->users;
    }

   /**
    * Add user
     *
     * @param \MySpace\MyBundle\Entity\Users $user
     *
     * @return Parcs
     */
    public function addUser(\MySpace\MyBundle\Entity\Users $user)
    {
        $this->users[] = $user;

        return $this;
    }

使用FOSUserBundle,为了访问连接的用户,在我的树枝视图中,我做了这个:{{ app.user.username }},它返回了当前用户的用户名。

现在,当我想添加parc时,我想以symfony形式(对于字段用户)检索此值。 这是我的parcsType.php表单:

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('parcName')
            ->add('users')
        ;
    }

这是我在树枝视图中的表格:

<form action="{{ path('addParcs_process') }}" method="POST" {{ form_enctype(form) }}>
  <div>
    {{ form_label(form.parcName, "Enter the parc name: ", {'label_attr': {'class': 'control-label'}}) }}
    {{ form_errors(form.parcName) }}
    {{ form_widget(form.parcName) }}
  </div>
  <div>
    {{ form_label(form.users, "Vous ajoutez ce parc en tant que: ", {'label_attr': {'class': 'control-label'}}) }}
    {{ form_errors(form.users) }}
    {{ form_widget(form.users, {'attr': {'value': app.user.username }}) }}
  </div>
  <input type="submit" value="Ajouter" class="btn btn-success"/>
</form>

正如您所看到的,我使用{{ app.user.username }}设置了我的用户字段的默认值,并且它有效,我的用户字段返回当前用户。但是,当我提交表单时,Parcs.phpUsers.php之间的用户字段和关联( ManyToMany )不会被保留/刷新。

这是我的控制器代码:

public function addParcsAction() {

    if (!$this->get('security.context')->isGranted('ROLE_EDIT')) {
      throw new HttpException("403");
    }

    $em=$this->getDoctrine()->getManager();
    $parc = new Parcs;

    $form=$this->createForm(new ParcsType(), $parc);
    $form->add('user');
    $request = $this->getRequest();

    if ($request->isMethod('POST') | ($form->isValid())) {

            $form->bind($request);

            $currentUser=$this->container->get('security.context')->getToken()->getUser();
            $parc->setUsers($currentUser);

            $parc = $form->getData();
            $em->persist($parc);
            $em->flush();

            return $this->redirect($this->generateUrl('indexParc'));
        }

    else {
            return $this->render('MySpaceMyBundle:Parcs:addParcs.html.twig', array('form' => $form->createView() ));
         }
}

提交效果很好,当我输入parc name的值时,数据在我的数据库中注册,但不是用户值和ManyToMany关联。

2 个答案:

答案 0 :(得分:3)

在创建表单之前,必须将User对象添加到Parc对象。这样您甚至不需要{'attr': {'value': app.user.username }}部分。

你可以试试这个:

public function addParcsAction() {

    if (!$this->get('security.context')->isGranted('ROLE_EDIT')) {
      throw new HttpException("403");
    }

    $em=$this->getDoctrine()->getManager();
    $parc = new Parcs;
    $currentUser = $this->container->get('security.context')->getToken()->getUser();
    $parc->addUser($currentUser);

    $form = $this->createForm(new ParcsType(), $parc);
    $request = $this->getRequest();

    if ($request->isMethod('POST') | ($form->isValid())) {

            $form->bind($request);

            $parc = $form->getData();
            $em->persist($parc);
            $em->flush();

            return $this->redirect($this->generateUrl('indexParc'));
        }

    else {
            return $this->render('MySpaceMyBundle:Parcs:addParcs.html.twig', array('form' => $form->createView() ));
         }
}

这样,您的表单将以当前用户作为users表单字段中的默认值生成

答案 1 :(得分:3)

我找到了解决方案,

正如here所述,只有拥有方负责连接管理。

问题不在于方法$parc->addUser($currentUser);,只是当想要保留数据时,实体Parcs不是管理此关系的所有者。

所以我反转了实体所有者属性。在Parcs.php中,关系必须是这样的:

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="Users", inversedBy="parcs")
 * @ORM\JoinTable(name="parcs_users",
 *   joinColumns={
 *     @ORM\JoinColumn(name="parc_id", referencedColumnName="id")
 *   },
 *   inverseJoinColumns={
 *     @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 *   }
 * )
 */
private $users;

为了写这个,我必须删除Users.php中的关系:

/**
 * @var \Doctrine\Common\Collections\Collection
 *
 * @ORM\ManyToMany(targetEntity="Parcs", mappedBy="users")
 */
private $parcs;

这是我addAction()的控制器:

public function addParcsAction() {

    if (!$this->get('security.context')->isGranted('ROLE_EDIT')) {
      throw new HttpException("403");
    }

    $em=$this->getDoctrine()->getManager();
    $parc = new Parcs;
    $currentUser = $this->container->get('security.context')->getToken()->getUser();
    $parc->addUser($currentUser);

    $form = $this->createForm(new ParcsType(), $parc);
    $request = $this->getRequest();

    if ($request->isMethod('POST') | ($form->isValid())) {

            $form->bind($request);

            $parc = $form->getData();
            $em->persist($parc);
            $em->flush();

            return $this->redirect($this->generateUrl('indexParc'));
        }

    else {
            return $this->render('MySpaceMyBundle:Parcs:addParcs.html.twig', array('form' => $form->createView() ));
         }
}

通过回答非常感谢,在这里注意到它不是$ parc-&gt; addUser($ currentUser);谁在制造麻烦,但是关系的所有者方面。