Skip to content

Instantly share code, notes, and snippets.

@czarpino
Last active December 17, 2015 14:39
Show Gist options
  • Save czarpino/5625692 to your computer and use it in GitHub Desktop.
Save czarpino/5625692 to your computer and use it in GitHub Desktop.
php, doctrine2, symfony2, form-validation

Refresh Entity on Failed Validation

An often overlooked step when updating an entity is reverting invalid changes. While often unnecessary, doing so is borderline good practice.

Here is a typical edit controller which renders a pre-filled form and validates changes to the entity being edited.

/**
 * Edit user attributes
 *
 * @param Request $request HTTP request object
 *
 * @return Response HTTP response object
 */
public function editUserAction(Request $request)
{
    $em = $this->getDoctrine()->getEntityManager();
    
    $user = $em->getRepository('FooDemoBundle:User')
               ->find($request->get('user_slug'));
              
    $userForm = $this->createForm(new UserType(), $user);
    
    if ('POST' === $request->getMethod()) {
        $userForm->bind($request->request->get($userForm->getName()));
        
        $isValid = $userForm->isValid();
        
        if ($isValid) {
            $em->flush();
            return $this->redirect($this->generateUrl('view_user'));
        }
    }
    
    return $this->render('FooDemoBundle:User:edit_user.html.twig', array (
        'userForm' => $userForm->createView(),
    ));
}

Since invoking $userForm->bind(...) also updates $user with the bound values, lines past $userForm->bind(...) will only have access to a $user object having the new attribute values.

// $user->getSlug() >> 'foo'

$userForm->bind($request->request->get($userForm->getName()));

// $user->getSlug() >> 'bar'

While this behavior conveniently saves additional code for updating the entity's attributes, it is especially undesirable when the updated values are invalid, and $user has to be used later in the controller, or in the template.

Since binding behavior is inherent to the form, the most convenient solution would be to revert the attribute values of the entity. To this end, Doctrine's EntityManager has refresh() which removes unpersisted changes to an entity.

$userForm->bind($request->request->get($userForm->getName()));
    
...

if (!isValid) {

    // Revert attribute values
    $em->refresh($foo);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment