Slimming down Symfony2 controller and persist logic
design-patterns, doctrine-orm, model-view-controller, symfony
Solution
I think it's a good idea to move your persist and remove logic out of your controllers, but the repository is not the correct place for it.
From the Symfony2 docs (http://symfony.com/doc/current/book/doctrine.html#fetching-objects-from-the-database):
You can think of a repository as a PHP class whose only job is to help you fetch entities of a certain class.
You should only be using your repository class for fetching data from the database.
I would move your persist/remove logic into a service (see http://symfony.com/doc/current/book/service_container.html) so your controller code would be something like
if($form->isValid()) :
$this->get('service.entity')->save($entity);
// Redirect the user to the default page
return $this->redirect($this->getOnNewSuccessRedirectUrl($entity));
endif;
Problem
From the point of view of MVC pattern and Symfony2, can i slim down my controller code just a bit, moving away some persist logic? For example, given a standard new action like this: ``` public function newAction(\Symfony\Component\HttpFoundation\Request $request) { // Create a new entity and a new form type for managing $entity = $this->createNewEntity(); $form = $this->createForm($this->createNewFormType(), $entity); // If it's GET just return the view if('GET' == $request->getMethod()) return array('form' => $form->createView()); // It's POST request so bind the form $form->bindRequest($request); // ... and if it's valid just persist the entity if($form->isValid()) : $em = $this->getEntityManager(); // Should be carried by controller? $em->persist($entity); // Should be carried by controller? $em->flush(); // Should be carried by controller? // Redirect the user to the default page return $this->redirect($this->getOnNewSuccessRedirectUrl($entity)); endif; // Return the view plus errors return array( 'errors' => $this->getValidator()->validate($entity), 'form' => $form->createView() ); } ``` Would be correct moving that logic to the repository? An example (warning: may not work): ``` class BaseRepository extends \Doctrine\ORM\EntityRepository { /** * Persist the entity (either new or existent) * * @param object $entity */ public function save($entity) { $em = $this->_em; $em->persist($entity); $em->flush(); } /** * Delete the entity. * * @param object $entity */ public function delete($entity) { $em = $this->_em; $em->remove($entity); $em->flush(); } } ``` The controller code would be: ``` if($form->isValid()) : $this->getRepository()->save($entity); // Redirect the user to the default page return $this->redirect($this->getOnNewSuccessRedirectUrl($entity)); endif; ```