我正在编写一个使用Zend Framework 2和Doctrine(都是最新的稳定版本)的应用程序。 有很多文档(主要是教程和博客文章)与Zend Form一起处理将教义实体保存到数据库。不幸的是,他们只处理没有一对多或多对多关系的简单实体。
这是我在自己的代码中采用的一个例子。
http://www.jasongrimes.org/2012/01/using-doctrine-2-in-zend-framework-2/
据我所知,在这个例子的Album Entity中,艺术家是一个字符串,以保持(已经冗长的)教程尽可能简单。但在现实世界的情况下,这当然是与艺术家实体(甚至是多对多)的一对多关系。在视图中,可以显示选择框,其中可以选择艺术家,列出可以在数据库中找到的所有艺术家实体,因此可以选择正确的艺术家实体。
按照相册的示例,这就是我在控制器中设置“编辑”动作的方式:
public function editAction()
{
// determine the id of the album we're editing
$id = $this->params()->fromRoute("id", false);
$request = $this->getRequest();
// load and set up form
$form = new AlbumForm();
$form->prepareElements();
$form->get("submit")->setAttribute("label", "Edit");
// retrieve album from the service layer
$album = $this->getSl()->get("Application\Service\AlbumService")->findOneByAlbumId($id);
$form->setBindOnValidate(false);
$form->bind($album);
if ($request->isPost()) {
$form->setData($request->getPost());
if ($form->isValid()) {
// bind formvalues to entity and save it
$form->bindValues();
$this->getEm()->flush();
// redirect to album
return $this->redirect()->toRoute("index/album/view", array("id"=>$id));
}
}
$data = array(
"album" => $album,
"form" => $form
);
return new ViewModel($data);
}
如果艺术家不是字符串,而是艺术家实体,那么如何更改此示例?
并且假设专辑还有多个跟踪实体,这些将如何处理?
答案 0 :(得分:0)
根本不需要更改示例,更改将在您的实体和表单中进行。
这是一个很好的参考:Doctrine Orm Mapping
因此,为了节省大量额外工作,您的OnToMany关系将使用:cascade = persist:
/**
* @ORM\OneToMany(targetEntity="Artist" , mappedBy="album" , cascade={"persist"})
*/
private $artist;
当涉及到持久化表单对象时,实体知道它也必须保存关联的实体。如果您不包含此内容,则必须使用集合手动执行此操作。
为了使表单更容易,您可以使用Doctrines Object Select,如下所示:
$this->add(
[
'type' => 'DoctrineModule\Form\Element\ObjectSelect',
'name' => 'artist',
'options' => [
'object_manager' => $this->objectManager,
'target_class' => 'Artist\Entity\Artist',
'property' => 'name', //the name field in Artist, can be any field
'label' => 'Artist',
'instructions' => 'Artists connected to this album'
],
'attributes' => [
'class' => '', //Add any classes you want in your form here
'multiple' => true, //You can select more than one artist
'required' => 'required',
]
]
);
所以现在你的表单为你处理集合,控制器根据你的例子不需要改变,因为实体将负责持久...
希望这能让你走上正轨。