douxu3732 2016-02-10 08:22
浏览 41

Symfony FormType PropertyAccessor.php错误

I am getting an error when saving data using a formType into a model that has a many to many relationship.

The error is

Catchable Fatal Error: Argument 1 passed to AppBundle\Entity\User::removeRole() must be an instance of AppBundle\Entity\Role, string given, called in /Code/project/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 616 and defined

What is the best way to inject the Role model into the form?

The model has the following:

/**
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
 * @ORM\JoinTable(name="user_roles")
 */
private $roles;

/**
 * Remove role
 *
 * @param Role $role
 */
public function removeRole(Role $role)
{
    $this->roles->removeElement($role);
}

/**
 * Add role
 *
 * @param Role $role
 *
 * @return User
 */
public function addRole(Role $role)
{
    $this->roles[] = $role;

    return $this;
}

There is the reverse in Role

/**
 *  @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
 */
private $users;

To save the data in the controller I have

    $user = new User();
    $form = $this->createForm(UserType::class, $user);
    $form->handleRequest($request);
    if( $form->isSubmitted() && $form->isValid() ){

        $encryptedPassword = $this->get('security.password_encoder')
            ->encodePassword($user, $user->getPlainPassword());
        $user->setPassword($encryptedPassword);

        $em = $this->getDoctrine()->getManager();
        $em->persist($user);
        $em->flush();
        return $this->redirect($this->generateUrl('user_list'));
    }
    return $this->render('user/new.html.twig', array('form' => $form->createView()));

And the FormType has

class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name')
        ->add('email')
        ->add('username')
        ->add('plainPassword', RepeatedType::class, array(
            'type' => PasswordType::class,
            'invalid_message' => 'The password fields must match.',
            'options' => array('attr' => array('class' => 'password-field')),
            'required' => true,
            'first_options'  => array('label' => 'Password'),
            'second_options' => array('label' => 'Repeat Password'),
        ))
        ->add('roles', EntityType::class, array(
            'class' => 'AppBundle:Role',
            'choice_label' => 'name',
            'multiple'    => true
        ));
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\User'
    ));
}

}
  • 写回答

1条回答 默认 最新

  • duangao8359 2016-02-10 14:33
    关注

    I have worked out and it was a little gotcha that was the issue is and may cause others the same.

    It is because:

    class User implements UserInterface
    

    which requires

    /**
     * @return mixed
     */
    public function getRoles()
    {
        return ARRAY|STRING;
    }
    

    To get around this I create:

    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
     * @ORM\JoinTable(name="user_roles")
     */
    private $userRoles;
    

    Everything then comes of getUserRoles and works fine.

    评论

报告相同问题?