2017-08-23 4 views
1

何かが欠落しているはずです。私の関連エンティティは以下のとおりです。Sonata 3:OneToMany関係のエンティティを削除すると 'by_reference' => falseとなりません

EducationalModule

namespace AppBundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* @ORM\Table(name="educational_module") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\CourseUnitRepository") 
* 
* Class EducationalUnit 
*/ 
class EducationalModule 
{ 
    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id() 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\EducationalUnitCategory", inversedBy="educationalUnits") 
    * @ORM\JoinColumn(name="category", referencedColumnName="course") 
    */ 
    private $category; 

    /** 
    * @var string 
    * 
    * @ORM\Column(type="string", nullable=false) 
    */ 
    private $name; 

    /** 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\Course", mappedBy="module") 
    */ 
    private $courses; 

    /** 
    * @ORM\OneToMany(targetEntity="AppBundle\Entity\EducationalUnit", mappedBy="module", cascade={"persist","remove"}, orphanRemoval=true) 
    * @ORM\OrderBy({"position" = "ASC"}) 
    * @Assert\Count(min="1", minMessage="Module has to have at least one unit.") 
    * @Assert\Valid() 
    */ 
    private $units; 


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

    /** 
    * @return mixed 
    */ 
    public function getCategory() 
    { 
     return $this->category; 
    } 

    /** 
    * @param mixed $category 
    */ 
    public function setCategory($category) 
    { 
     $this->category = $category; 
    } 

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

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

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

    /** 
    * @return mixed 
    */ 
    public function getCourses() 
    { 
     return $this->courses; 
    } 

    /** 
    * @return Collection 
    */ 
    public function getUnits() 
    { 
     return $this->units; 
    } 


    public function setUnits(Collection $units) 
    { 
     $this->units = new ArrayCollection(); 

     foreach ($units as $unit) { 
      $this->addUnits($unit); 
     } 

     return $this; 
    } 


    public function addUnits(EducationalUnit $unit) 
    { 
     $unit->setModule($this); 
     $this->units->add($unit); 
    } 

    /** 
    * @param $unit string 
    * 
    * @return $this 
    */ 
    public function removeUnits($unit) 
    { 
     $this->units->removeElement($unit); 

     return $this; 
    } 
} 

EducationalUnit

namespace AppBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* @ORM\Table(name="educational_unit") 
* @ORM\Entity(repositoryClass="AppBundle\Repository\CourseUnitRepository") 
* 
* Class EducationalUnit 
*/ 
class EducationalUnit 
{ 
    /** 
    * @ORM\Column(type="integer") 
    * @ORM\Id() 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\EducationalModule", inversedBy="units") 
    */ 
    private $module; 

    /** 
    * @ORM\Column(type="string", length=255, nullable=false) 
    */ 
    private $name; 

    /** 
    * @ORM\Column(type="integer", options={"default" : 0}) 
    */ 
    private $position = 0; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\EducationalUnitCategory", inversedBy="educationalUnits") 
    * @ORM\JoinColumn(name="category", referencedColumnName="course") 
    */ 
    private $category; 

    /** 
    * @var EducationalFile 
    * 
    * @ORM\OneToOne(targetEntity="AppBundle\Entity\EducationalFile", cascade={"persist","remove"}, orphanRemoval=true) 
    * @Assert\NotBlank() 
    * @Assert\Valid() 
    */ 
    private $file; 

    /** 
    * @return mixed 
    */ 
    public function getCategory() 
    { 
     return $this->category; 
    } 

    /** 
    * @param mixed $category 
    */ 
    public function setCategory($category) 
    { 
     $this->category = $category; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getModule() 
    { 
     return $this->module; 
    } 


    public function setModule($module) 
    { 
     $this->module = $module; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getPosition() 
    { 
     return $this->position; 
    } 

    /** 
    * @param mixed $position 
    */ 
    public function setPosition($position) 
    { 
     $this->position = $position; 
    } 

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

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

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

    /** 
    * @return EducationalFile 
    */ 
    public function getFile() 
    { 
     return $this->file; 
    } 

    /** 
    * @param EducationalFile $file 
    */ 
    public function setFile($file) 
    { 
     $this->file = $file; 
    } 
} 

私の管理エンティティ:

EducationalModuleAdmin

namespace AppBundle\Admin; 

use AppBundle\Entity\EducationalFile; 
use AppBundle\Entity\EducationalModule; 
use AppBundle\Entity\EducationalUnit; 
use Sonata\AdminBundle\Admin\AbstractAdmin; 
use Sonata\AdminBundle\Datagrid\DatagridMapper; 
use Sonata\AdminBundle\Datagrid\ListMapper; 
use Sonata\AdminBundle\Form\FormMapper; 

/** 
* Class EducationalModuleAdmin 
*/ 
class EducationalModuleAdmin extends AbstractAdmin 
{ 
    protected function configureFormFields(FormMapper $formMapper) 
    { 

     $formMapper->add('name', 'text'); 
     $formMapper->add('units', 'sonata_type_collection', [ 
      'required' => true, 
      'by_reference' => false, // Has to be false. Thanks to that, our children entities will receive a reference to the parent. 
      'btn_add' => 'Add unit', 
     ], [ 
      'edit' => 'inline', 
      'inline' => 'table', 
      'sortable' => 'position', 
      'multiple' => true, 
     ]); 

    } 

    protected function configureDatagridFilters(DatagridMapper $datagridMapper) 
    { 
     $datagridMapper->add('id'); 
     $datagridMapper->add('name'); 
    } 

    protected function configureListFields(ListMapper $listMapper) 
    { 
     $listMapper->add('id'); 
     $listMapper->add('name'); 
     $listMapper->add('_action', 'actions', [ 
      'actions' => [ 
       'show' => [], 
       'edit' => [], 
       'delete' => [], 
      ], 
     ]); 
    } 
} 

EducationalUnitAdmin

namespace AppBundle\Admin; 

use Sonata\AdminBundle\Admin\AbstractAdmin; 
use Sonata\AdminBundle\Datagrid\DatagridMapper; 
use Sonata\AdminBundle\Datagrid\ListMapper; 
use Sonata\AdminBundle\Form\FormMapper; 

/** 
* Class EducationalUnitAdmin 
*/ 
class EducationalUnitAdmin extends AbstractAdmin 
{ 
    protected $parentAssociationMapping = 'module'; 

    protected function configureFormFields(FormMapper $formMapper) 
    { 
     $is_creation = !$this->id($this->getSubject()); 

     $formMapper->add('module', 'sonata_type_model_hidden', [ 
      'attr' => ['hidden' => true], 
     ]); 

     $formMapper->add('id', 'integer', [ 
      'disabled' => true, 
     ]); 

     $formMapper->add('name', 'text'); 


     $formMapper->add('file', 'sonata_type_admin', [ 
      'required' => $is_creation, 
      'by_reference' => true, 
     ], [ 
      'edit' => 'inline', 
      //'inline' => 'table', 
     ]); 

     $formMapper->add('position', 'hidden', [ 
      'attr' => ['hidden' => true], 
     ]); 
    } 

    protected function configureDatagridFilters(DatagridMapper $datagridMapper) 
    { 
     $datagridMapper->add('id'); 
    } 

    protected function configureListFields(ListMapper $listMapper) 
    { 
     $listMapper->add('id'); 
    } 
} 

私はまた私が持っている(EducationalModuleの子である)すべてのEducationalUnitの横にあるチェックボックスを「削除」、私のEducationalModuleエンティティを編集しています。チェックボックスを選択してEducationalModuleを更新しても、EducationalUnitは削除されません。

興味深いのは、私がEducationalModuleAdmin'by_reference' => falseからtrueに変更すると、削除されてしまうということです(ただし、作成された子どもには親に対する参照がありません)。

は、私はかなり徹底的にそれをデバッグしようとした私は、企業が実際にソナタの ModelManager->persist()->flush()に入る前に変更されていることを確認することができますが、何らかの理由で、子供の数の変化は、最終的に保持されません。

答えて

1

setUnitsメソッドを削除してください。 by_reference => falseが設定されている場合、Sonataはadd/removeメソッドを見つけます。今のところsetUnitsメソッドだけが使用されています。このメソッドでは、存在しないもののバインドを解除するのではなく、エントリとの関係を設定します。

また、メソッドの名前をaddUnitremoveUnitに変更する必要があります。

+0

'setUnits'メソッドを削除すると、' NoSuchPropertyException'というメッセージが表示されます。 ''プロパティのアクセスタイプを判断できませんでした。 :( –

+0

親の内部で削除されたものを「アンバインド」する方法はありますか? –

+1

あなたの助けを借りて、解決策を見つけました。これは違うが類似していて、かなりばかげていました。これは正しいので、symfonyのautomagicは実際に私の複数のプロパティの単数名を探しているので、それらは 'addUnit'と' removeUnit'であるべきです。私はもっと怒っているのか、それとも驚いているのか分かりません。 .. –

関連する問題