【问题标题】:cascading manytomany relationship symfony insertion and edit级联多对多关系 symfony 插入和编辑
【发布时间】:2018-03-28 12:56:46
【问题描述】:

我在这里寻求你的帮助,我希望我能找到一些帮助 我有一个级联的多对多关系,我想插入objectif 我在partenaire指示者之间有很多关系, 指示者和安妮之间的多对多 和annee objectif之间的onetomany

这意味着一个partenaire可以有很多objectif,每个objectif都属于一个annee,并且一个annee bellong to指示你

这是我对树枝的看法

<ul class="spancabine">
                                                    <div>
                                                        <label class="checkbox-inline">
                                                            {% for indicateur in indicateures %}
                                                            <li class="check-ser">
                                                                <label class="check">
                                                                    <span><input name="indicateur[]"
                                                                               onchange="change_checkbox(this)"
                                                                               type="checkbox"
                                                                               class="indicateur{{ indicateur.id }}"
                                                                               value="{{ indicateur.id }}">{{ indicateur.titre }} </span>
                                                                </label>
                                                            </li>
                                                        </label>
                                                    </div>
                                                    <div>
                                                        <label class="checkbox-inline">
                                                            <div class="show{{ indicateur.id }}" style="  display: none; margin-left: 100px">
                                                                {% for annee in indicateur.annee %}
                                                                    <li class="check-ser">
                                                                        <label class="check">
                                                                    <span><input type="checkbox" name="annee[]"
                                                                               class="annee{{ annee.id }}"
                                                                               alt="{{ annee.id }}{{ indicateur.id }}"
                                                                               onchange="change_checkboxx(this)"
                                                                               value="{{ annee.id }}">{{ annee.annee }}  </span>
                                                                        </label>
                                                                    </li>
                                                                    <li class="check-ser">
                                                                        <label class="check">
                                                                    <span>
                                                                        <div class="object{{ annee.id }}{{ indicateur.id }}" style="display: none !important;">
                                                                            <input class="object{{ annee.id }}"
                                                                                   type="text" name="objectif[]"
                                                                                   value="" style="">
                                                                        </div> </span>
                                                                        </label>
                                                                    </li>
                                                                    <br>
                                                                {% endfor %}
                                                            </div>
                                                            <br>
                                                            {% endfor %}
                                                            {#<input type="checkbox" value="">Indicateur 1#}
                                                        </label>
                                                    </div>

                                                </ul>

这是我在控制器中插入的操作

public function AjouterPartenaireAction(Request $request) {
    $partenaire = new Partenaire();
    $form = $this->createForm('ApfeBundle\Form\PartenaireType', $partenaire);
    $form->handleRequest($request);
    $indicateures=$request->get('indicateur');
    $annees=$request->get('annee');
    $objectifs=$request->get('objectif');
    $em = $this->getDoctrine()->getManager();
    foreach ($indicateures as $indicateur) {
        $indicateure     = $em->getRepository('ApfeBundle:Indicateure')->findOneById($indicateur);
        foreach ($annees as $annee) {
            $annee = $em->getRepository('ApfeBundle:Annee')->findOneById($annee);
            $annee->addIndicateure($indicateure);
            $em->persist($annee);
            $em->flush();
        }
        $partenaire->addIndicateure($indicateure);
    }
    $em->persist($partenaire);
    $em->flush();
    $mi = new \MultipleIterator();
    $mi->attachIterator(new \ArrayIterator($annees));
    $mi->attachIterator(new \ArrayIterator($objectifs));
    $mi->attachIterator(new \ArrayIterator($indicateures));
    foreach ($mi as $value) {
        $annees =  $value[0];
        $objectif = $value[1];
        $idindicateur = $value[2];
        $em1 = $this->getDoctrine()->getManager();
        $indicateure     = $em->getRepository('ApfeBundle:Indicateure')->findOneById($idindicateur);
        $annee     = $em->getRepository('ApfeBundle:Annee')->findOneById($annees);

        $obejctif = new Objectif();
        $obejctif->setAnneeId($annee);
        $obejctif->setObjectif($objectif);
        $obejctif->setPartenaireId($partenaire);
        $obejctif->setIndicateureId($indicateure);
        $em1->persist($obejctif);
        $em1->flush();
    }

    $form = $this->createForm(new PartenaireType(), $partenaire);
    $form->handleRequest($request);
    $em = $this->getDoctrine()->getManager();
    $idpartenaire = $partenaire->getId();
    $partenaires = $em->getRepository('ApfeBundle:Partenaire')->findAll();
    return $this->container->get('templating')->renderResponse('partenaire/new.html.twig', array(
        'idpartenaire' => $idpartenaire,
        'partenaires' => $partenaires,
    ));
}

问题是当我提交它时没有正确插入我的所有条目 如下图所示

有人可以帮忙,谢谢

【问题讨论】:

  • 请问有什么建议或者类似的例子吗

标签: symfony-2.8


【解决方案1】:

好的。这将是一个很长的帖子。很抱歉。

这是我复制您的问题的方法。

首先创建实体。我为此使用 yml,所以如果您使用注解,那么您的工作就是将 yml 样式转换为注解样式。

//AppBundle/Resource/config/doctrine/Annee.orm.yml
AppBundle\Entity\Annee:
    type: entity
    table: null
    repositoryClass: AppBundle\Repository\AnneeRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    manyToMany:
        indicateurs:
            targetEntity: AppBundle\Entity\Indicateur
            mappedBy: annees
            cascade: ['persist']
            fetch: EAGER
    oneToMany:
        objectifes:
            targetEntity: AppBundle\Entity\Objectif
            mappedBy: annee
            cascade: ['persist', 'remove']
            orphanRemoval: true
            nullable: true
    fields:
        name:
            type: string
            length: 255
    lifecycleCallbacks: {  }


//AppBundle/Resource/config/doctrine/Indicateur.orm.yml
    AppBundle\Entity\Indicateur:
    type: entity
    table: null
    repositoryClass: AppBundle\Repository\IndicateurRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    manyToMany:
        annees:
            targetEntity: AppBundle\Entity\Annee
            inversedBy: indicateurs
            joinTable:
                name: annees_indicateurs
                joinColumns:
                    indicateur_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    annee_id:
                        referencedColumnName: id
            cascade: ['persist', 'remove']
            fetch: EAGER
        partenaires:
            targetEntity: AppBundle\Entity\Partenaire
            mappedBy: indicateurs
            cascade: ['persist']
            fetch: EAGER
    fields:
        name:
            type: string
            length: 255
    lifecycleCallbacks: {  }


//AppBundle/Resources/config/doctrine/Objectif.orm.yml
AppBundle\Entity\Objectif:
    type: entity
    table: null
    repositoryClass: AppBundle\Repository\ObjectifRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    manyToOne:
        annee:
            targetEntity: AppBundle\Entity\Annee
            inversedBy: objectifes
            joinColumn:
                name: annee_id
                referencedColumnName: id
            cascade: ['persist']
    fields:
        name:
            type: string
            length: 255
    lifecycleCallbacks: {  }


//AppBundle/Resources/config/doctrine/Partenaire.orm.yml
AppBundle\Entity\Partenaire:
    type: entity
    table: null
    repositoryClass: AppBundle\Repository\PartenaireRepository
    id:
        id:
            type: integer
            id: true
            generator:
                strategy: AUTO
    manyToMany:
        indicateurs:
            targetEntity: AppBundle\Entity\Indicateur
            inversedBy: partenaires
            joinTable:
                name: indicateurs_partenaires
                joinColumns:
                    partenaire_id:
                        referencedColumnName: id
                inverseJoinColumns:
                    indicateur_id:
                        referencedColumnName: id
            cascade: ['persist', 'remove']
            fetch: EAGER
    fields:
        name:
            type: string
            length: 255
    lifecycleCallbacks: {  }

下一步是设置学说的方法。这些将在内部用于采取行动。

//AppBundle/Entity/Annee.php
//pay attention to the way addIndicateur(), removeIndicateur() methods are wrote. They are essential so that the many-to-many between Annee and Indicateur entities to work. The same for Indicateur.php and Partenaire.php
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Annee
 */
class Annee
{
    /**
     * @var int
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $objectifes;

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $indicateurs;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->objectifes = new \Doctrine\Common\Collections\ArrayCollection();
        $this->indicateurs = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Annee
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
    */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add objectife
     *
     * @param \AppBundle\Entity\Objectif $objectife
     * @return Annee
     */
    public function addObjectife(\AppBundle\Entity\Objectif $objectife)
    {
        $this->objectifes[] = $objectife;

        return $this;
    }

    /**
     * Remove objectife
     *
     * @param \AppBundle\Entity\Objectif $objectife
     */
    public function removeObjectife(\AppBundle\Entity\Objectif $objectife)
    {
        $this->objectifes->removeElement($objectife);
    }

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

    /**
     * Add indicateur
     *
     * @param \AppBundle\Entity\Indicateur $indicateur
     * @return Annee
     */
    public function addIndicateur(\AppBundle\Entity\Indicateur $indicateur)
    {
        if ($this->indicateurs->contains($indicateur)) {
            return;
        }

        $this->indicateurs[] = $indicateur;
        $indicateur->addAnnee($this);

        return $this;
    }

    /**
     * Remove indicateur
     *
     * @param \AppBundle\Entity\Indicateur $indicateur
     */
    public function removeIndicateur(\AppBundle\Entity\Indicateur $indicateur)
    {
        if (!$this->indicateurs->contains($indicateur)) {
            return;
        }

        $this->indicateurs->removeElement($indicateur);
        $indicateur->removeAnnee($this);
    }

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



//AppBundle/Entity/Indicateur.php
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Indicateur
 */
class Indicateur
{
    /**
     * @var int
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Indicateur
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $annees;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->annees = new \Doctrine\Common\Collections\ArrayCollection();
        $this->partenaires = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add annee
     *
     * @param \AppBundle\Entity\Annee $annee
     * @return Indicateur
     */
    public function addAnnee(\AppBundle\Entity\Annee $annee)
    {
        if ($this->annees->contains($annee)) {
            return;
        }

        $this->annees[] = $annee;
        $annee->addIndicateur($this);

        return $this;
    }

    /**
     * Remove annee
     *
     * @param \AppBundle\Entity\Annee $annee
     */
    public function removeAnnee(\AppBundle\Entity\Annee $annee)
    {
        if (!$this->annees->contains($annee)) {
            return;
        }

        $this->annees->removeElement($annee);
        $annee->removeIndicateur($this);
    }

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

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $partenaires;

    /**
     * Add partenaire
     *
     * @param \AppBundle\Entity\Partenaire $partenaire
     * @return Indicateur
     */
    public function addPartenaire(\AppBundle\Entity\Partenaire $partenaire)
    {
        if ($this->partenaires->contains($partenaire)) {
            return;
        }

        $this->partenaires[] = $partenaire;
        $partenaire->addIndicateur($this);

        return $this;
    }

    /**
     * Remove partenaire
     *
     * @param \AppBundle\Entity\Partenaire $partenaire
     */
    public function removePartenaire(\AppBundle\Entity\Partenaire $partenaire)
    {
        if (!$this->partenaires->contains($partenaire)) {
            return;
        }

        $this->partenaires->removeElement($partenaire);
        $partenaire->removeIndicateur($this);
    }

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



//AppBundle/Entity/Objectif.php
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Objectif
 */
class Objectif
{
    /**
     * @var int
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Objectif
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @var \AppBundle\Entity\Annee
     */
    private $annee;

    /**
     * Set annee
     *
     * @param \AppBundle\Entity\Annee $annee
     * @return Objectif
     */
    public function setAnnee(\AppBundle\Entity\Annee $annee = null)
    {
        $this->annee = $annee;

        return $this;
    }

    /**
     * Get annee
     *
     * @return \AppBundle\Entity\Annee 
     */
    public function getAnnee()
    {
        return $this->annee;
    }
}



//AppBundle/Entity/Partenaire.php
<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Partenaire
 */
class Partenaire
{
    /**
     * @var int
     */
    private $id;

    /**
     * @var string
     */
    private $name;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Partenaire
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @var \Doctrine\Common\Collections\Collection
     */
    private $indicateurs;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->indicateurs = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add indicateur
     *
     * @param \AppBundle\Entity\Indicateur $indicateur
     * @return Partenaire
     */
    public function addIndicateur(\AppBundle\Entity\Indicateur $indicateur)
    {
        if ($this->indicateurs->contains($indicateur)) {
            return;
        }

        $this->indicateurs[] = $indicateur;
        $indicateur->addPartenaire($this);

        return $this;
    }

    /**
     * Remove indicateur
     *
     * @param \AppBundle\Entity\Indicateur $indicateur
     */
    public function removeIndicateur(\AppBundle\Entity\Indicateur $indicateur)
    {
        if (!$this->indicateurs->contains($indicateur)) {
            return;
        }

        $this->indicateurs->removeElement($indicateur);
        $indicateur->removePartenaire($this);
    }

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

接下来,表格(类型)。我为每个实体使用了php app/console doctrine:generate:crud,并将结果形式更改为:

//AppBundle/Form/AnneeType.php
<?php

namespace AppBundle\Form;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AnneeType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('indicateurs', EntityType::class, [
                'class' => 'AppBundle:Indicateur',
                'placeholder' => 'Choose an Indicateur',
                'choice_label' => function($indicateurs) {
                    return $indicateurs->getName();
                },
                'multiple' => true,
                'expanded' => false,
                'by_reference' => false,
            ])
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Annee'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_annee';
    }
}




//AppBundle/Form/IndicateurType.php
<?php

namespace AppBundle\Form;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class IndicateurType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('partenaires', EntityType::class, [
                'class' => 'AppBundle:Partenaire',
                'placeholder' => 'Choose a Partenaire',
                'choice_label' => function($partenaire) {
                    return $partenaire->getName();
                },
                'multiple' => true,
                'expanded' => false,
                'by_reference' => false,
            ])
            ->add('annees', EntityType::class, [
                'class' => 'AppBundle:Annee',
                'placeholder' => 'Choose an Annee',
                'choice_label' => function($annee) {
                    return $annee->getName();
                },
                'multiple' => true,
                'expanded' => false,
                'by_reference' => false,
            ])
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Indicateur'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_indicateur';
    }
}




//AppBundle/Form/ObjectifType.php
<?php

namespace AppBundle\Form;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class ObjectifType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('annee', EntityType::class, [
                'class' => 'AppBundle:Annee',
                'placeholder' => 'Select Annee',
                'choice_label' => function($annee) {
                    return $annee->getName();
                },
                'multiple' => false,
                'expanded' => false
            ])
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Objectif'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_objectif';
    }
}





//AppBundle/Form/PartenaireType.php
<?php

namespace AppBundle\Form;

use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PartenaireType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('indicateurs', EntityType::class, [
                'class' => 'AppBundle:Indicateur',
                'placeholder' => 'Choose an Indicateur',
                'choice_label' => function($indicateur) {
                    return $indicateur->getName();
                },
                'multiple' => true,
                'expanded' => false,
                'by_reference' => false,
            ])
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Partenaire'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_partenaire';
    }
}

对于渲染,我使用了默认的 crud 表单,并添加了 novalidate 属性(适用于所有表单):

{{ form_start(form,{attr:{'novalidate':'novalidate'}}) }}

我使用了默认的 CRUD 控制器和路由。如果您像我一样在为每个实体创建 CRUD 时使用 yaml,那么您需要将主 routing.yml 文件导入 app/config/routing.yml

crud:
    resource: '@AppBundle/Resources/config/routing.yml'

否则,如果您使用注释,则一切就绪。

【讨论】:

  • 您好,非常感谢您的帮助,我真的非常感谢您,我最大的问题是,在我的伙伴身上,我必须感染我想要的指示物和 annees,并且我会放一张图片我必须尊重的石墨i.stack.imgur.com/m3pM7.jpg
  • 所以对指标的影响,我在指标管理中进行。但是在partenaires的管理中,我必须影响指标(与他们的annees(并且每个annee都有它自己的objectif)))partenaires Partenaire[ManyToMany] Indicateur Indicateur[ManyToMany] Année Année [OneToMany,Bidirectional] Objectif
猜你喜欢
  • 2010-12-15
  • 2018-06-28
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多