2014-12-29 3 views
0

Я очень новичок в Symfony2, и теперь у меня есть проблема с набором форм. У меня есть две Сущности. Пользователь Entity и роль Entity.Symfony2 - Коллекция форм - Обновление -ManytoMany-Relation

Entity Пользователь

/** 
* @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 Роль

/** 
* @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(); 
} 

Контроллер

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); 

} 

Теперь у меня есть коллекция форм с пользователем и роли, которая сохраняется в БД для Пользователь. Когда я делаю изменения в роли, я получил ошибку «Исключение произошло при выполнении» UPDATE pso_role SET role =? WHERE id =? ' с параметрами ["ROLE_ADMIN", 2] "

Проблема в том, что Symfony хочет внести изменения в таблицу для роли Entity. На самом деле это должна быть новая запись в таблице для отношения User-Role. Я искал в Google и здесь, в stackoverflow, но я не могу найти то, что мне нужно изменить.

Я думаю, что проблема может быть, 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'))); 

это может быть, что линия добавить ('роли', 'сбор', массив (=> нового RoleType()) 'типа') определяет объект, который должен быть обновлен? Могу ли я изменить это

Если я не использую его с коллекцией форм, но только с одной формой, все работает нормально, потому что тогда затрагивается только одна сущность. Я был бы рад, если кто-нибудь может дать мне подсказку.

Теперь я попробовал его в Formbuilder с -> Add ('роли', 'сущность', массив ('класс' => 'PsoLogBundle: Role', 'свойство' => 'роль'))

Затем я получаю сообщение об ошибке «Ни свойства« роли », ни один из методов« setRoles() »,« __set() »или« __call() »не существуют и имеют открытый доступ в классе« Pso \ LogBundle \ Entity \ Пользователь «»

Я пытался вставить в Entity пользователя сеттера

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

Тогда я получаю ошибку ContextErrorExc eption: Catchable Fatal Error: аргумент 1, переданный в Pso \ LogBundle \ Entity \ User :: setRoles(), должен быть экземпляром Pso \ LogBundle \ Entity \ ArrayCollection, экземпляром Pso \ LogBundle \ Entity \ Role, указанным в C: \ xampp \ htdocs \ pso \ vendor \ symfony \ symfony \ src \ Symfony \ Component \ PropertyAccess \ PropertyAccessor.php в строке 347 и определяется в C: \ xampp \ htdocs \ pso \ src \ Pso \ LogBundle \ Entity \ User.php линия 99

Я пытался решить проблему с

 'multiple' => false, 

как я нашел в here

Но это не меняет ситуацию.

Я добавил (а) пользователю.PHP сеттера для роли

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

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

     $this->addPo($po); 
    } 

} 

Когда я делаю это и генерировать сеттеры и геттеры новый, я не получаю сообщение об ошибке, когда я изменить роль для пользователя, но в БД запись не изменится.

После многих часов поиска я получил его для работы сейчас. Правильный сеттер прав. Кроме того, я изменил формообразователь, как

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

Теперь роль меняется правильно, когда я отправляю форму. Спасибо, что всегда отвечал, так что я получил правильное направление. Надеюсь, теперь все будет хорошо.

Приветствия Micha

+0

Я думаю, что проблема может быть, formbuilder [код] $ строителем \t \t -> добавить ('имя пользователя', 'текст', массив ('метки' => 'Имя пользователя')) \t \t \t -> Add ('электронная почта', 'электронная почта', массив ('метки' => 'Электронная почта')) \t \t \t -> добавить ('IsActive', 'текст', массив ('label' => 'User aktiv')) \t \t \t -> добавить ('Роли', 'коллекция', массив ('type' => new RoleType())) \t \t \t -> Добавить ('Submit', 'отправить', массив ( \t \t \t \t 'атр' => массив ( \t \t \t \t \t 'formnovalidate' => 'formnovalidate' \t \t \t \t) \t \t \t)); [/ code] может быть, что строка add ('Roles', 'collection', array ('type' => new RoleType())) определяет объект, который необходимо обновить? Могу ли я изменить это – Micha

+0

Можете ли вы добавить этот код в свой OP? –

+0

Просьба поделиться полями отображения обоих объектов. вам также нужно определить имя третьей таблицы. см. это> link > http://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html#annref-manytomany –

ответ

0

Вы должны иметь в своем объекта пользователя:

/** 
    * @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; 

В вашей роли объекта:

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

в вашей роли конструктора:

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

Вместо сбора будет множественного выбора:

->add('roles', 'entity', array(
      'class' => 'YourBundle:Role', 
      'property' => 'name', 
     )) 
+0

Спасибо за ваш намек. Ситуация не меняется. Когда я создал объекты, я сделал это как http://symfony.com/doc/current/cookbook/security/entity_provider.html#managing-roles-in-the-database. Правильно ли это было? Или ваш способ определения правильный или лучший способ? – Micha

Смежные вопросы