2016-12-04 44 views
0

我有2個實體和多對多的關聯:ManyToMany協會。如何將所有者實體添加到逆實體?

/** 
* @ORM\Entity 
* @ORM\Table(name="m2m_table1") 
*/ 
class Table1 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", nullable=false, options={"unsigned":true}) 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToMany(targetEntity="Table2", inversedBy="table1", fetch="LAZY", cascade="all") 
    * @ORM\JoinTable(name="m2m_links", 
    *  joinColumns={@ORM\JoinColumn(name="table1_id", referencedColumnName="id")}, 
    *  inverseJoinColumns={@ORM\JoinColumn(name="table2_id", referencedColumnName="id")} 
    *  ) 
    */ 
    private $table2; 
    ... 
} 

/** 
* @ORM\Entity 
* @ORM\Table(name="m2m_table2") 
*/ 
class Table2 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer", nullable=false, options={"unsigned":true}) 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToMany(targetEntity="Table1", mappedBy="table2", fetch="LAZY", cascade="all") 
    */ 
    private $table1; 
    ... 
} 

而且我希望有機會逆實體添加到實體店主,反之亦然。我可以向所有者實體添加逆實體,但我無法將所有者實體添加到逆實體。

$table1 = $em->find('XxxM2mBundle:Table1', 1); 
$table2 = $em->find('XxxM2mBundle:Table2', 1); 
$table2->addTable1($table1); 
$em->flush($table2); 

未添加鏈接。示例被簡化了,實際上有兩種形式,第一種爲表格1調整鏈接,第二種爲表格2調整鏈接。我用它Symfony\Bridge\Doctrine\Form\Type\EntityType。 2-nd格式不適用於此配置。

Form類:

namespace Xxx\M2mBundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 
use Symfony\Component\Form\Extension\Core\Type as FormType; 
use Symfony\Bridge\Doctrine\Form\Type as DoctrineFormType; 

class Table2 extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->setMethod('post') 
      ->add('name', FormType\TextType::class, [ 
       'required' => true, 
       'label' => 'Name', 
      ]) 
      ->add('table1', DoctrineFormType\EntityType::class, [ 
       'required' => false, 
       'expanded' => true, 
       'multiple' => true, 
       'class' => 'Xxx\\M2mBundle\\Entity\\Table1', 
       'choice_label' => 'name', 
       'label' => 'Table1', 
      ]) 
      ->add('save', FormType\SubmitType::class, [ 
       'label' => 'Save', 
      ]); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults([ 
      'data_class' => 'Xxx\\M2mBundle\\Entity\\Table2', 
     ]); 
    } 
} 

我已經改變了協會Table2到:

/** 
* @ORM\ManyToMany(targetEntity="Table1", inversedBy="table2", fetch="LAZY", cascade="all") 
* @ORM\JoinTable(name="m2m_links", 
*  joinColumns={@ORM\JoinColumn(name="table2_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="table1_id", referencedColumnName="id")} 
*  ) 
*/ 
private $table1; 

它幫助,但我認爲這是不好的決定,現在我得到錯誤The table with name 'm2m_links' already exists.當我嘗試更新模式./bin/console doctrine:schema:update --dump-sql --force

回答

2

您需要了解關於Owning and Inverse side of the association

這是你如何能夠與多對多協會工作的順利開展:

  1. 生成您需要使用CLI例如兩個enities

    bin/console doctrine:generate:entity

  2. doctrine association mapping for ManyToMany bidirectional

  3. 註釋和構造函數添加到您的實體。不要忘記在註釋之前寫上ORM\。將實體和表名稱更改爲您自己的情況。

  4. 在所有者一方或您與cascade = {「persist」}選項關係的雙方擴展ManyToMany註釋。例如

    @ORM\ManyToMany(targetEntity="Tag", inversedBy="images", cascade={"persist"})

  5. 自動生成所需的方法和更新與CLI模式。

    bin/console doctrine:generate:entities AppBundle

    bin/console doctrine:schema:update --force

  6. 添加__toString()方法兩個實體。

  7. 如果您希望能夠在反轉實體上添加所有者實體,您可以對反轉實體的添加和刪除方法進行一些小改動,如下例所示。

例如:

# Tag entity 

public function addImage(\AppBundle\Entity\Image $image) 
{ 
    $image->addTag($this); // new rule! 
    $this->images[] = $image; 

    return $this; 
} 

public function removeImage(\AppBundle\Entity\Image $image) 
{ 
    $image->removeTag($this); // new rule! 
    $this->images->removeElement($image); 
} 
  • 添加'by_reference' => false到實體表單字段選項
  • 例如:

    class TagType extends AbstractType 
    { 
        /** 
        * {@inheritdoc} 
        */ 
        public function buildForm(FormBuilderInterface $builder, array $options) 
        { 
         $builder 
           ->add('name') 
           ->add('images', EntityType::class, array(
            'multiple' => true, 
            'expanded' => true, 
            'class' => 'AppBundle:Image', 
            'by_reference' => false # HERE! 
           )) 
         ; 
        } 
    
    // .. 
    
    +0

    它與簡化的例子,並不適用於表單。 –

    +0

    它也適用於我的表單。你能顯示你的formType類嗎? (應該住在SomeBundle/Form目錄中) –

    +0

    是的,我已經加了 –