#php #doctrine-orm #zend-framework2
#php #doctrine-orm #zend-фреймворк2
Вопрос:
У меня есть 3 сущности доктрины:
- Продукт
- Магазин
- ProductStore
Мне нужно иметь форму, которая позволяет управлять связями между ними с помощью коллекций форм Zend.
Добавление конечного редактирования работает хорошо, но удаление не сохраняется в базе данных. Другими словами, необходимые элементы удаляются из коллекции, но это не отражается в базе данных.
Вот ProductsController:
<?php
class ProductsController extends AbstractActionController
{
public function linkAction()
{
$request = $this->getRequest();
$id = (int)$this->params()->fromRoute('id', null);
$em = $this->getEntityManager();
$formManager = $this->getServiceLocator()->get('FormElementManager');
$form = $formManager->get('ProductLinkForm');
$item = $em->find('ApplicationEntityProduct', $id);
$form->bind($item);
if ($this->request->isPost()) {
$form->setData($this->request->getPost());
if ($form->isValid()) {
$em->persist($item);
$em->flush();
return $this->redirect()->toRoute(...);
}
}
return new ViewModel(array(
'form' => $form,
'item' => $item,
));
}
}
Набор полей:
class ProductLinkFieldset extends Fieldset
{
protected $objectManager;
public function __construct(ObjectManager $objectManager)
{
parent::__construct('product_link_fieldset');
$this->objectManager = $objectManager;
}
public function init()
{
$this->setHydrator(new DoctrineHydrator($this->objectManager))
->setObject(new Product());
$this->add(array(
'type' => 'ZendFormElementCollection',
'name' => 'productStores',
'options' => array(
'count' => 0, // minimum elements count
'should_create_template' => true,
'allow_add' => true,
'allow_remove' => true,
'target_element' => array(
'type' => 'ProductStoreFieldset',
),
)
));
}
}
Product
Сущность является:
/**
* Product
*
* @ORMTable(name="Product")
* @ORMEntity
*/
class Product
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
* @ORMId
* @ORMGeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="name", type="string", precision=0, scale=0, nullable=false, unique=false)
*/
private $name;
/**
* @var DoctrineCommonCollectionsCollection
*
* @ORMOneToMany(targetEntity="ApplicationEntityProductStore", mappedBy="product", cascade={"persist"})
*/
private $productStores;
/**
* Constructor
*/
public function __construct()
{
$this->productStores = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add productStores
*
* @param Collection $productStores
*/
public function addProductStores(Collection $productStores)
{
foreach ($productStores as $productStore) {
$productStore->setProduct($this);
$this->productStores->add($productStore);
}
}
/**
* Remove productStores
*
* @param Collection $productStores
*/
public function removeProductStores(Collection $productStores)
{
foreach ($productStores as $productStore) {
# if I uncomment this, there will be an error when persisting the entity:
# An exception occurred while executing
# 'UPDATE product_store SET product_id = ? WHERE id = ?' with params [null, 4]:
# Column can not be null.
// $productStore->setProduct(null);
$this->productStores->removeElement($productStore);
}
return $this;
}
}
и ProductStore
сущность:
/**
* ProductStore
*
* @ORMTable(name="product_store")
* @ORMEntity
*/
class ProductStore
{
/**
* @var integer
*
* @ORMColumn(name="id", type="integer", precision=0, scale=0, nullable=false, unique=false)
* @ORMId
* @ORMGeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORMColumn(name="url", type="string", precision=0, scale=0, nullable=false, unique=false)
*/
private $url;
/**
* @var ApplicationEntityProduct
*
* @ORMManyToOne(targetEntity="ApplicationEntityProduct", inversedBy="productStores", cascade={"persist","remove"})
* @ORMJoinColumns({
* @ORMJoinColumn(name="product_id", referencedColumnName="id", nullable=false)
* })
*/
private $product;
/**
* @var ApplicationEntityStore
*
* @ORMManyToOne(targetEntity="ApplicationEntityStore", inversedBy="storeProducts")
* @ORMJoinColumns({
* @ORMJoinColumn(name="store_id", referencedColumnName="id", nullable=false)
* })
*/
private $store;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set product
*
* @param ApplicationEntityProduct $product
* @return ProductStore
*/
public function setProduct(ApplicationEntityProduct $product = null)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* @return ApplicationEntityProduct
*/
public function getProduct()
{
return $this->product;
}
/**
* Set store
*
* @param ApplicationEntityStore $store
* @return ProductStore
*/
public function setStore(ApplicationEntityStore $store = null)
{
$this->store = $store;
return $this;
}
/**
* Get store
*
* @return ApplicationEntityStore
*/
public function getStore()
{
return $this->store;
}
}
Итак, проблема в том, что удаленные элементы все еще находятся в базе данных, несмотря на то, что они удаляются из коллекции перед сохранением.
Ответ №1:
Это то, что мне было нужно: http://docs.doctrine-project.org/en/latest/reference/working-with-associations.html#orphan-removal
Проблема решена.