Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slimming down Symfony2 controller and persist logic

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;
like image 351
gremo Avatar asked May 10 '12 23:05

gremo


2 Answers

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;
like image 54
Chris McKinnel Avatar answered Sep 24 '22 00:09

Chris McKinnel


Chris is absolutely right.

But by the way:

Why do you validate you entity again in this way:

'errors' => $this->getValidator()->validate($entity)?

You bind the request to the form, so the errors are processed in the created view in the viewhelpers 'form_errors(...)'.

like image 39
tweini Avatar answered Sep 26 '22 00:09

tweini