これは、長い年月を経て返信されます。そのために残念。
問題の再現方法は次のとおりです。
まず、エンティティを作成します。私はそのために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
を使用し、私のようになったフォームを変更:
{{ form_start(form,{attr:{'novalidate':'novalidate'}}) }}
:レンダリングのために
//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';
}
}
、私は(フォームのすべてのための)novalidate
属性を追加して、デフォルトのCRUDフォームを使用しました
私はデフォルトのCRUDコントローラとルートを使用しました。あなたは、各エンティティのCRUDを作成するとき、あなたはapp/config/routing.yml
にメインrouting.yml
ファイルをインポートする必要があります、私のように、YAMLを使用している場合:
crud:
resource: '@AppBundle/Resources/config/routing.yml'
そうでない場合、あなたは注釈を使用している場合、あなたがしています準備完了。
どんな提案してくださいまたは下さい –