У меня есть приложение, в котором я использую PHP с Zend Framework и Doctrine2 в качестве ORM. Мой вопрос связан с тем, что контролер предпочтительно должен знать о базовой модели и уровне персистентности. В идеале я бы сказал, что это «ничто» сам - контроллер не должен ничего знать о том, как / когда сущности сохраняются. Однако я чувствую, что это не всегда лучшее решение (?).
Я пытался следовать руководству по проектированию «разделения интересов». Я сделал это путем создания сервисного уровня, который выполняет операции CRUD на моих моделях. Смотрите следующий пример:
public function testbuildAction()
{
// create section
$sectionService = new \MyAPP\Model\Service\Acl\SectionService();
$sectionA = $sectionService->createSection('SectionA-NAME');
// create privilege with the above section
$privilegeService = new \MyAPP\Model\Service\Acl\PrivilegeService();
$privilegeA = $privilegeService->createPrivilege(
$sectionA,
\MyAPPFrameWork\Model\Acl\Privilege::PERMISSION_EDIT
);
// create a role with the privilege above. A role must have at least one priv.
$roleService = new \MyAPP\Model\Service\Acl\RoleService();
$role = $roleService->createRole('Role-NAME', $privilegeA);
// this loads a managed User object (managed by EntityManager)
$user = $this->_helper->IdentityLoader();
$user->addRole($role); // add the role to this user
$userService = new \MyAPP\Model\Service\Core\UserService();
$userService->updateUser($user); // persist the updates.
}
Как вы можете видеть, Контроллер ничего не знает о постоянстве, но для получения этого результата мне нужно выполнять оба метода: persist () и flush () внутри каждого вызова методов createXXX () или updateXXX () уровня обслуживания. , Я бы предпочел сделать что-то вроде этого:
public function testbuildAction()
{
// create section
$sectionService = new \MyAPP\Model\Service\Acl\SectionService();
$sectionA = $sectionService->createSection('SectionA-NAME');
// create privilege with the above section
$privilegeService = new \MyAPP\Model\Service\Acl\PrivilegeService();
$privilegeA = $privilegeService->createPrivilege(
$sectionA,
\MyAPPFrameWork\Model\Acl\Privilege::PERMISSION_EDIT
);
// create a role with the privilege above. A role must have at least one priv.
$roleService = new \MyAPP\Model\Service\Acl\RoleService();
$role = $roleService->createRole('Role-NAME', $privilegeA);
// this loads a managed User object (managed by EntityManager)
$user = $this->_helper->IdentityLoader();
$user->addRole($role); // add the role to this user
// persist it all (all service-classes access the same entitymanager).
$roleService->flush(); // everything is persisted
}
Но это приводит к сбою Doctrine2, так как он сохраняет объекты в базе данных в неправильном порядке - привилегии сохраняются до разделов (не знаю, могу ли я поручить Doctrine выполнить это упорядоченным образом ??). Привилегии получают неверный идентификатор для разделов, которые еще не сохранены.
В любом случае, большая проблема здесь заключается в том, должен ли я пытаться отложить сброс до тех пор, пока не будут созданы все объекты и не установлены отношения. Цель состоит в том, чтобы иметь ОДНУ транзакцию, которая выполняет всю запись в базу данных - которая, следовательно, должна быть инициирована контроллером (поскольку она единственная, кто знает, когда выполняется объект и построение отношений), тем самым «загрязняя» контроллер знаниями о персистентный слой?