【问题标题】:How can i remove a form item which is a oneToMany relation如何删除作为 oneToMany 关系的表单项
【发布时间】:2015-06-11 08:18:19
【问题描述】:

我有两个实体。容器和学校类型。实体容器与实体 Schooltype 具有“oneToMany”关系。

实体容器:

/**
     * @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;

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

实体容器,学校类型的移除方法:

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

表单容器类型:

->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()));

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

【问题讨论】:

    标签: symfony


    【解决方案1】:

    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;
        }
    }
    

    联赛类型

    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'));
    }
    

    【讨论】:

    • 非常感谢您的支持。但我想通过取消选择 ContainerTypeForm 中的实体 Schooltype 来删除/删除 Container 和 Schooltype 之间的关系。如果我从 ContainerTypeForm 中取消选择一个 schooltype 并保留 Container,则不会删除该关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    • 2014-08-02
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多