У меня есть приложение, в котором я использую PHP с картой Zend и Doctrine2 как ORM. Мой вопрос связан с тем, насколько контроллер должен знать о базовой модели и уровне персистентности. В идеале я бы сказал, что это «ничего» - контроллер не должен знать ничего о том, как/когда сущности сохраняются. Однако я считаю, что это не всегда лучшее решение (?).Разделение проблем - где флеш() в структуре MVC (контроллер против servicelayer)
Я попытался выполнить «директиву по разделению интересов». Я сделал это, создав сервисный уровень, который выполняет операции 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.
}
Как вы можете видеть контроллер ничего не знает о настойчивости не знаю, но, чтобы получить этот результат мне нужно выполнить как сохраняться() и флеш() внутри каждого вызова 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 на неудачу, поскольку оно сохраняется объекты в базу данных в неправильном порядке - льготы сохранялись до того разделов (Незнайка, если я могу поручить Доктрины выполнить это в упорядоченном порядке?). Привилегии получают неверный идентификатор для разделов, которые еще не сохраняются.
В любом случае, большая проблема заключается в том, следует ли пытаться отложить промывку до тех пор, пока не будут созданы все объекты и не будут установлены отношения. Цель состоит в том, чтобы иметь транзакцию ONE, которая выполняет всю запись в базу данных, что, следовательно, должно быть вызвано контроллером (поскольку это единственный, кто знает, как происходит создание объекта и отношения WHEN), тем самым «загрязняя» контроллер знаниями слой устойчивости?
Doctrine2 реализует шаблон работы, но как можно сказать, что этот образец срабатывает? Вы говорите, что ваш уровень сервиса контролирует это, но знает ли он, когда контроллер завершил добавление/удаление/обновление объектов? Единственный способ, который я вижу, - сделать явный entityManager-> flush() в контроллере, чтобы это произошло? – Aleksander 2010-11-25 10:59:38