如何删除一个oneToMany关系的表单项

时间:2015-06-11 08:18:20

标签: symfony

我有两个实体。容器和学校类型。实体容器有一个" oneToMany"与实体Schooltype的关系。

实体容器:

/**
     * @ORM\OneToMany(targetEntity="App\MyBundle\Entity\SchoolType", mappedBy="container", cascade={"persist", "remove"})
     */
    protected $schooltype;

实体学校类型:

 /**
     * @ORM\ManyToOne(targetEntity="App\MyBundle\Entity\Container", inversedBy="schooltype")
     * @ORM\JoinColumn(name="container_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $container;

现在我为容器创建一个表单,所以我可以添加一个或多个schooltypes。在我的实体Container中我修改了" removeSchooltype"方法,它看起来像。

实体容器,删除schooltype的方法:

public function removeSchooltype(\App\MyBundle\Entity\SchoolType $schooltype)
    {
        $this->schooltype->removeElement($schooltype);
        $schooltype->setContainer(null);
    }

表单ContainerType:

->add('schooltype', 'entity', array(
                    'class' => 'AppMyBundle:Schooltype',
                    'choices' => $schoolTypes,
                    'label' => 'msg.schoolType',
                    'translation_domain' => 'messages',
                    'multiple' => true,
                    'expanded' => false)
                )

我尝试在控制器中处理存储过程。

容器控制器,编辑方法:

$object = new Container();

        // Exists any object?
        if (!$object) {
            $this->get('session')->getFlashBag()->add('danger', $this->get('translator')->trans('notfound'));
            return $this->redirect($this->generateUrl('app_container_list'));
        }

        $form = $this->createForm($this->get('form.type.container'), $object)->add('save', 'submit', array('label' => 'save', 'translation_domain' => 'messages', 'attr' => array('class' => 'btn btn-primary')));

        $form->handleRequest($request);

        // Check if form isValid
        if ($form->isValid()) {
            // Store object
            $em = $this->getDoctrine()->getManager();

            $em->persist($object);

            // Flush statements
            $em->flush();
            $em->clear();

            $this->get('session')->getFlashBag()->add('info', $this->get('translator')->trans('objectEdited', array()));
            return $this->redirect($this->generateUrl('app_container_list'));
        }

        return $this->render('AppMyBundle:Container:edit.html.twig', array("form" => $form->createView()));

一切正常,我可以在我的容器中添加一个或多个学校类型,这是成功保存的。但是,如果我从表格中的selectbox中删除一个schooltype并发布我的表单,容器和schooltype之间的关系将不会被删除,有人暗示为什么会发生这种情况?

1 个答案:

答案 0 :(得分:0)

1个国家到N联赛。下面的示例显示了如何完成工作。只需申请你的。如果您想要1到N个关系的完整CRUD示例,it is here.

<强>国家

class Country
{
    protected $id;

    /**
     * @ORM\OneToMany(
     *      targetEntity="League",
     *      mappedBy="country",
     *      cascade={"persist", "remove"}
     * )
     */
    protected $league;

    public function __construct()
    {
        $this->league = new ArrayCollection();
    }

    public function addLeague(League $league)
    {
        $this->league[] = $league;
        return $this;
    }

    public function removeLeague(League $league)
    {
        $this->league->removeElement($league);
    }

    public function getLeague()
    {
        return $this->league;
    }
}

<强>联赛

class League
{
    /**
     * @ORM\ManyToOne(
     *      targetEntity="Country",
     *      inversedBy="league"
     * )
     * @ORM\JoinColumn(
     *      name="country_id",
     *      referencedColumnName="id",
     *      onDelete="CASCADE",
     *      nullable=false
     * )
     */
    protected $country;

    public function setCountry(Country $country)
    {
        $this->country = $country;
        return $this;
    }

    public function getCountry()
    {
        return $this->country;
    }
}

<强> LeagueType

class LeagueType extends AbstractType
{
    private $country;

    public function __construct()
    {
        $this->country = [
            'class' => 'FootballFrontendBundle:Country',
            'property' => 'name',
            'multiple' => false,
            'expanded' => false,
            'required' => false,
            'empty_value' => '',
            'query_builder' => function (EntityRepository $repo)
            {
                return $repo->createQueryBuilder('c')->orderBy('c.name', 'ASC');
            }
        ];
    }

    public function buildForm(FormBuilderInterface $builder, array $options = [])
    {
        $builder
            ->setMethod($options['method'])
            ->setAction($options['action'])
            ->add('whatever properties you have in your entitiy')
            ->add('country', 'entity', $this->country);
    }

    public function getName()
    {
        return 'league';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(
            ['data_class' => 'Football\FrontendBundle\Entity\League']
        );
    }
}

控制器删除/删除方法

/**
 * Deletes country.
 *
 * @param int $id
 *
 * @Route("/delete/{id}", requirements={"id"="\d+"})
 * @Method({"GET"})
 *
 * @return RedirectResponse|Response
 * @throws LeagueException
 */
public function deleteAction($id)
{
    try {
        $em = $this->getDoctrine()->getEntityManager();
        $repo = $em->getRepository('FootballFrontendBundle:League');

        $league = $repo->findOneByIdAsObject($id);
        if (!$league instanceof League) {
            throw new LeagueException(sprintf('League read: league [%s] cannot be found.', $id));
        }

        $em->remove($league);
        $em->flush();
    } catch (DBALException $e) {
        $message = sprintf('DBALException [%s]: %s', $e->getCode(), $e->getMessage());
    } catch (ORMException $e) {
        $message = sprintf('ORMException [%s]: %s', $e->getCode(), $e->getMessage());
    } catch (Exception $e) {
        $message = sprintf('Exception [%s]: %s', $e->getCode(), $e->getMessage());
    }

    if (isset($message)) {
        throw new LeagueException($message);
    }

    return $this->redirect($this->generateUrl('where ever you want'));
}