dongyun234854 2014-12-29 20:26 采纳率: 0%
浏览 47
已采纳

Symfony2 - 表单集合 - 更新-ManytoMany-Relation

I'm very new to Symfony2 and now I have a problem with a collection of forms. I have two Entities. The Entity User and the Entity Role.

Entity User

/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(type="string", length=25, unique=true)
 */
private $username;

/**
 * @ORM\Column(type="string", length=32)
 */
private $salt;

/**
 * @ORM\Column(type="string", length=250)
 */
private $password;

/**
 * @ORM\Column(type="string", length=60, unique=true)
 */
private $email;



/**
 * @ORM\Column(name="is_active", type="boolean")
 */
private $isActive;

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

Entity Role

/**
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id()
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(name="name", type="string", length=30)
 */
private $name;

/**
 * @ORM\Column(name="role", type="string", length=20, unique=true)
 */
private $role;

/**
 * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
 * @ORM\JoinTable(name="user_role",
 *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
 *      )
 */
private $users;

public function __construct()
{
    $this->users = new ArrayCollection();
}

Controller

public function editUserAction($id, Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $user = $em->getRepository('PsoLogBundle:User')->find($id);
    $form =  $this->createForm(new NewUserType(),$user);
    $form->handleRequest($request);
    if (!$user) {
        throw $this->createNotFoundException(
            'No news found for id ' . $id
        );
    }


    if ($form->isValid()) {
        $em->flush();
    $this->get('session')->getFlashBag()->add('notice', 'User updated successfully');
    }

    $build['form'] = $form->createView();

    return $this->render('PsoLogBundle:Security:editUser.html.twig', $build);

}

Now I have a collection of Forms with the user and the Role, that is saved in DB for the User. When I make a change on the Role I got the error "An exception occurred while executing 'UPDATE pso_role SET role = ? WHERE id = ?' with params ["ROLE_ADMIN", 2]"

The Problem is that Symfony wants to make the change on the Table for the Entity Role. In fact it should be an new entry in the table for the relationship User - Role. I searched in Google and here in stackoverflow but I can't find what i have to change.

I think the problem is perhaps the formbuilder

$builder ->add('username','text', array('label' => 'Username')) 
     ->add('email','email', array('label' => 'Email')) 
     ->add('isActive','text', array('label' => 'User aktiv')) 
     ->add('Roles', 'collection', array('type' => new RoleType())) 
     ->add('Submit', 'submit', array( 'attr'=> array ( 'formnovalidate' => 'formnovalidate' )));

could it be, that the line add('Roles', 'collection', array('type' => new RoleType())) defines the entity, which should be updated? Can i change this

If I don't use it with a collection of forms, but only with a single form, everything works fine, because then only one entity is affected. I would be glad, if somebody can give me a hint.

Now I tried it in the Formbuilder with ->add('roles', 'entity', array('class' => 'PsoLogBundle:Role','property' => 'role'))

Then I get the error "Neither the property "roles" nor one of the methods "setRoles()", "__set()" or "__call()" exist and have public access in class "Pso\LogBundle\Entity\User". "

I tried to insert in Entity User the setter

public function setRoles( ArrayCollection $roles)
{
$this->roles = $roles;
return $this;
}    

Then I get the error ContextErrorException: Catchable Fatal Error: Argument 1 passed to Pso\LogBundle\Entity\User::setRoles() must be an instance of Pso\LogBundle\Entity\ArrayCollection, instance of Pso\LogBundle\Entity\Role given, called in C:\xampp\htdocs\pso\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php on line 347 and defined in C:\xampp\htdocs\pso\src\Pso\LogBundle\Entity\User.php line 99

I tried to solve the problem with

      'multiple' => false,

like I found in here

But that doesn't change the situation.

I added in the user.php a setter for the role

// Important
public function setRoles($roles)
{
    foreach($roles as $p)
    {
        $po = new user_role();

        $po->setUser($this);
        $po->setRoles($p);

        $this->addPo($po);
    }

}   

When I do this and generate setters and getters new, I get no error, when I change the role for a user, but in DB the entry doesn't change.

After many hours searching, I got it to work now. The setter before is right. Additionally I changed the formbuilder like

->add('roles', 'entity', array('class' => 'PsoLogBundle:Role','property' => 'role','multiple' => true,))

Now the role changes correctly, when I submit the form. Thanks for evereybody answering, so that I got the right direction. I hope, everything works fine now.

Greetings Micha

  • 写回答

1条回答 默认 最新

  • du6jws6975 2014-12-30 06:04
    关注

    You should have in your user entity :

        /**
         * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
         * @ORM\JoinTable(name="role_assigned_to_user",
         *      joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")},
         *      inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
         *      )
         */
        private $roles;
    

    In your role entity:

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

    in your role constructor:

        public function __construct() {
           $this->users = new \Doctrine\Common\Collections\ArrayCollection();
        }
    

    Instead of collection it will multi select:

    ->add('roles', 'entity', array(
                'class' => 'YourBundle:Role',
                'property' => 'name',
            ))
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料