奏鸣曲3:删除一对多关系中的实体不适用于"by_reference"=> false



我一定错过了什么。我的相关实体是:

EducationalModule

namespace AppBundleEntity;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineCommonCollectionsCollection;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMTable(name="educational_module")
* @ORMEntity(repositoryClass="AppBundleRepositoryCourseUnitRepository")
*
* Class EducationalUnit
*/
class EducationalModule
{
/**
* @ORMColumn(type="integer")
* @ORMId()
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORMManyToOne(targetEntity="AppBundleEntityEducationalUnitCategory", inversedBy="educationalUnits")
* @ORMJoinColumn(name="category", referencedColumnName="course")
*/
private $category;
/**
* @var string
*
* @ORMColumn(type="string", nullable=false)
*/
private $name;
/**
* @ORMOneToMany(targetEntity="AppBundleEntityCourse", mappedBy="module")
*/
private $courses;
/**
* @ORMOneToMany(targetEntity="AppBundleEntityEducationalUnit", mappedBy="module", cascade={"persist","remove"}, orphanRemoval=true)
* @ORMOrderBy({"position" = "ASC"})
* @AssertCount(min="1", minMessage="Module has to have at least one unit.")
* @AssertValid()
*/
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 AppBundleEntity;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
* @ORMTable(name="educational_unit")
* @ORMEntity(repositoryClass="AppBundleRepositoryCourseUnitRepository")
*
* Class EducationalUnit
*/
class EducationalUnit
{
/**
* @ORMColumn(type="integer")
* @ORMId()
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORMManyToOne(targetEntity="AppBundleEntityEducationalModule", inversedBy="units")
*/
private $module;
/**
* @ORMColumn(type="string", length=255, nullable=false)
*/
private $name;
/**
* @ORMColumn(type="integer", options={"default" : 0})
*/
private $position = 0;
/**
* @ORMManyToOne(targetEntity="AppBundleEntityEducationalUnitCategory", inversedBy="educationalUnits")
* @ORMJoinColumn(name="category", referencedColumnName="course")
*/
private $category;
/**
* @var EducationalFile
*
* @ORMOneToOne(targetEntity="AppBundleEntityEducationalFile", cascade={"persist","remove"}, orphanRemoval=true)
* @AssertNotBlank()
* @AssertValid()
*/
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 AppBundleAdmin;
use AppBundleEntityEducationalFile;
use AppBundleEntityEducationalModule;
use AppBundleEntityEducationalUnit;
use SonataAdminBundleAdminAbstractAdmin;
use SonataAdminBundleDatagridDatagridMapper;
use SonataAdminBundleDatagridListMapper;
use SonataAdminBundleFormFormMapper;
/**
* 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 AppBundleAdmin;
use SonataAdminBundleAdminAbstractAdmin;
use SonataAdminBundleDatagridDatagridMapper;
use SonataAdminBundleDatagridListMapper;
use SonataAdminBundleFormFormMapper;
/**
* 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然后删除作品时(但还有另一个问题 - 创建的孩子没有对父母的引用(。

我试图非常彻底地调试它,我可以确认该实体确实在进入 Sonata 的ModelManager->persist()->flush()之前进行了修改,但由于某种原因,孩子数量的变化最终没有持续。

尝试删除setUnits方法。如果设置了by_reference => false,Sonata 应该找到add/remove方法。目前仅使用setUnits方法,在此方法中,您仅设置与条目的关系,而不取消绑定不存在的条目。

您还应该将方法重命名为addUnitremoveUnit

相关内容

  • 没有找到相关文章

最新更新