假设我有一个公司,我管理Employees, Cars, Contracts, Buildings, Sites, Products,
等等。您可以猜测,这些是非常独立的事情,因此不可能有继承。
对于这些元素中的每一个(即实体),我希望能够附加一个或多个Document
s(单击按钮,表单打开,选择一个/多个{ {1}}或上传新的。)
将Document
链接到一种实体不是问题,我的问题是有多种实体。我应该如何管理?我有两个有自己问题的想法......:
有什么建议吗?
[编辑]
事实上,我必须对Document
执行相同的操作:我需要将一些Event
与某些Events
和/或某些Employees
等相关联。在我的实际情况中,我有超过10个实体与Cars
和/或Event
相关联,这意味着如果我使用解决方案1,则会复制20倍以上的代码!
答案 0 :(得分:1)
假设您正在使用Doctrine ORM,我认为您正在搜索Mapped Superclasses继承。
文档比文字更好:
答案 1 :(得分:0)
所以最后我设法解决了我的问题,遵循@ Rpg600关于Mapped Superclasses的想法。
这可能不是有史以来最好,最干净的解决方案,我并不为此感到骄傲,但它确实起到了作用,它仍然比我的第一个想法更好。
我创建了一个BaseEntity
,这是我的映射超类(Employee
,Car
等。实体必须扩展此类):
/**
* BaseEntity
* @ORM\MappedSuperclass
*/
class BaseEntity {
/**
* @ORM\OneToOne(targetEntity="MyProject\MediaBundle\Entity\Folder")
*/
private $folder;
/**
* Set folder
* @param \Webobs\MediaBundle\Entity\Folder $folder
* @return BaseEntity
*/
public function setFolder(\Webobs\MediaBundle\Entity\Folder $folder = null){
$this->folder = $folder;
return $this;
}
/**
* Get folder
* @return \Webobs\MediaBundle\Entity\Folder
*/
public function getFolder(){
return $this->folder;
}
}
由于在超类中不可能有多对多关系,我使用的Folder
将包含一个或多个Document
。这是解决方案的肮脏部分; folder
表基本上只包含一个字段,即id ...
class Folder
{
private $id;
/**
* Note : Proprietary side
* @ORM\ManyToMany(targetEntity="MyProject\MediaBundle\Entity\Document", inversedBy="folders", cascade={"persist"})
* @ORM\JoinTable(name="document_in_folder")
*/
private $documents;
// setters and getters
然后我创建一个帮助类(声明为服务)来管理任何Entity
和Document
之间的链接:
class DocumentHelper extends Controller
{
protected $container;
/** ************************************************************************
* Constructor
* @param type $container
**************************************************************************/
public function __construct($container = null)
{
$this->container = $container;
}
/** ************************************************************************
* Attach Document(s) to an $entity according to the information given in the
* form.
* @param Entity $entity
* @param string $redirectRouteName Name of the route for the redirection after successfull atachment
* @param string $redirectParameters Parameters for the redirect route
* @return Response
**************************************************************************/
public function attachToEntity($entity, $redirectRouteName, $redirectParameters)
{
$folder = $entity->getFolder();
if($folder == NULL){
$folder = new Folder();
$entity->setFolder($folder);
}
$form = $this->createForm(new FolderType(), $folder);
// ------------- Request Management ------------------------------------
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$form->bind($request); // Link Request and Form
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($folder);
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl($redirectRouteName, $redirectParameters));
}
}
return $this->render('MyProjectMediaBundle:Folder:addDocument.html.twig', array(
'form' => $form->createView(),
'entity' => $entity,
));
}
这样做,我只需要在每个相关控制器中添加一个小动作,比如EmployeeController.php
:
public function addDocumentAction(Employee $employee)
{
$redirectRouteName = 'MyProjectCore_Employee_see';
$redirectParameters = array('employee_id' => $employee->getId());
return $this->get('myprojectmedia.documenthelper')->attachToEntity($employee,$redirectRouteName,$redirectParameters);
}
显示的原理相同,在帮助器中我有我在已存在的seeAction()
中调用的常用功能,在TWIG文件中我导入了常见的“文档列表”显示。
那是所有人!
我希望这有助于:)