How to set related entity id in one to many relationship Symfony? - symfony

I am trying to persist two entities that have OneToMany and ManyToOne relationships.
I'm trying to embed a collection of forms inside a form.
I have a many to one related entities and everytime I create a new CurriculumVitae which is related to Candidat the column candidat_id_id is null.
Only the entity CurriculumVitae is successfully created and persisted except the Candidat id in the data datatable.
CurriculumVitae Table
id | titre | candidat_id_id | id_education
candidat_id_id is: null
id_education has this value: Doctrine\Common\Collections\ArrayCollection#000000003d585f990000000052235238
Education Table is empty
id | description | id_curriculum_vitae_id
My problem is with the id_curriculum_vitae_id and the id_education.
CurriculumVitae Entity:
/**
* CurriculumVitae
*
* #ORM\Table(name="curriculum_vitae")
* #ORM\Entity(repositoryClass="GE\CandidatBundle\Repository\CurriculumVitaeRepository")
*/
class CurriculumVitae
{
/**
* #var Candidat
*
* #ORM\ManyToOne(targetEntity="GE\CandidatBundle\Entity\Candidat")
*/
protected $candidatId;
/**
* #var Education
* #ORM\OneToMany(targetEntity="GE\CandidatBundle\Entity\Education", mappedBy="idCurriculumVitae", cascade={"persist", "remove"})
* #ORM\Column(name="id_education")
*/
protected $educations;
/**
* Add education
*
* #param \GE\CandidatBundle\Entity\Education $education
*
* #return CurriculumVitae
*/
public function addEducation(\GE\CandidatBundle\Entity\Education $education)
{
$this->educations[] = $education;
$education->setCurriculumVitae($this);
return $this;
}
/**
* Remove education
*
* #param \GE\CandidatBundle\Entity\Education $education
*/
public function removeEducation(\GE\CandidatBundle\Entity\Education $education)
{
$this->educations->removeElement($education);
}
}
Education Entity:
/**
* Education
*
* #ORM\Table(name="education")
* #ORM\Entity(repositoryClass="GE\CandidatBundle\Repository\EducationRepository")
*/
class Education
{
...
/**
* #var CurriculumVitae
* #ORM\ManyToOne(targetEntity="GE\CandidatBundle\Entity\CurriculumVitae")
*/
private $idCurriculumVitae;
}
CurriculumVitaeController :
class CurriculumVitaeController extends Controller
{
/**
* Creates a new curriculumVitae entity.
*
* #Route("/candidat/cv/ajouter", name="cv_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$curriculumVitae = new Curriculumvitae();
$form = $this->createForm('GE\CandidatBundle\Form\CurriculumVitaeType', $curriculumVitae);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($curriculumVitae);
$em->flush();
$request->getSession()
->getFlashBag()
->add('infoCv', 'Votre cv a été bien enregistrée.');
return $this->redirectToRoute('cv_show', array('id' => $curriculumVitae->getId()));
}
return $this->render('curriculumvitae/new.html.twig', array(
'curriculumVitae' => $curriculumVitae,
'form' => $form->createView(),
));
}
}
CurriculumVitaeType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('candidat', EntityType::class, array(
'class' => 'GECandidatBundle:Candidat',
'choice_label' => 'id',
'multiple' => false,
))
->add('educations',
CollectionType::class, [
'entry_type' => EducationType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'label' => 'Educations:'
]
)
;
}

Try this code and update your database's schema
/**
* #var CurriculumVitae
* #ORM\ManyToOne(targetEntity="GE\CandidatBundle\Entity\CurriculumVitae")
*#ORM\JoinColumn(name="candidatId",referencedColumnName="id",onDelete="SET NULL")
*/
private $idCurriculumVitae;

Sorry, i found my problem.
the id must be defined in the Controller.
$curriculumVitae->setCandidat($candidat);

Related

Symfony - Can't get a way to read the property (PropertyAccessor)

I develop with symfony a form for create tickets but when i try i got this error:
my function buildform from the file tickettype.php:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Titre', TextType::class)
->add('Message', TextType::class)
->add('Date', DateTimeType::class, ['data' => new \DateTime()] )
->add('Demandeur', EntityType::class, [
'class' => Client::class,
'choice_label' => 'Nom',
])
->add('Agent', EntityType::class, [
'class' => Dealer::class,
'choice_label' => 'Nom',
])
->add('Etat_Ticket', EntityType::class, [
'class' => Etat::class,
'choice_label' => 'Statut',
]);
}
and in the controller :
/**
* #Route("/add/", name="add_ticket")
*
* #param Request $request
* #return \Symfony\Component\HttpFoundation\Response
*/
public function addTicketAction(Request $request)
{
$ticket = new Ticket();
$form = $this->createForm(TicketType::class, $ticket);
$form->add('send', SubmitType::class, ['label' => 'créé un nouveau ticket']);
$form->handleRequest($request);
if($form->isSubmitted()){
$ticket->setDate(new \DateTime());
$em = $this->getDoctrine()->getManager();
$em->persist($ticket);
$em->flush();
return $this->redirectToRoute('List_ticket');
}
return $this->render("add.html.twig", array('form' => $form->createView()));
}
and my entity Ticket have this property:
/**
* #ORM\ManyToOne(targetEntity=Etat::class, inversedBy="Etat_Ticket")
* #ORM\JoinColumn(nullable=false)
*/
private $Etat_Ticket;
link to the entity Etat which look like this :
/**
* Etat
*
* #ORM\Table(name="etat")
* #ORM\Entity
*/
class Etat
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="statut", type="string", length=255, nullable=false)
*/
private $statut;
public function getId(): ?int
{
return $this->id;
}
public function getStatut(): ?string
{
return $this->statut;
}
public function setStatut(string $statut): self
{
$this->statut = $statut;
return $this;
}
}
You don't have a getter for Etat_Ticket property, so symfony (and that's a PHP common rule, when the property is not public) can't read its value from outside class scope. Symfony Form component, here, is trying by default to use the getter or access the property directly if it were public, and as neither getter nor public property are found, it symply doesn't know how to retrieve the value.
You can feed the form by yourself (docs) or use property_path.
Remember also that binding entities (or in general the domain model) directly to a form is good for RAD (rapid application development) but not so good in the long term. I would suggest to use a sort of DTO in order to read and write from and to the model (take a look here in order to get an idea about this concept)

symfony - dropdown menu doesn't select the option

I made a page on symfony to administrate some products with a dropdown menu linked to a category table.
The categoryid is well saved on the product, but the dropdown never select the good option, I don't find why.
Here is the category part in my class Dproduct :
/**
* #ORM\ManyToOne(targetEntity=RCategory::class, inversedBy="products")
* #ORM\JoinColumn(name="categoryId", referencedColumnName="categoryId", onDelete="CASCADE")
*/
private $categoryId;
public function getCategoryId(): ?RCategory
{
return $this->categoryId;
}
public function setCategoryId(?RCategory $categoryId): self
{
$this->categoryId = $categoryId;
return $this;
}
here is my class RCategory:
/**
* RCategory
*
* #ORM\Table(name="r_category")
* #ORM\Entity
*/
class RCategory
{
/**
* #var int
*
* #ORM\Column(name="categoryId", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $categoryId;
/**
* #var string
*
* #ORM\Column(name="categoryLib", type="string", length=50, nullable=false)
*/
private $categoryLib;
/**
* #Gedmo\Slug(fields={"categoryLib"})
* #ORM\Column(type="string", length=128, unique=true)
*/
public function getCategoryId(): ?int
{
return $this->categoryId;
}
public function getCategoryLib(): ?string
{
return $this->categoryLib;
}
public function setCategoryLib(string $categoryLib): self
{
$this->categoryLib = $categoryLib;
return $this;
}
here is my buildForm function :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('categoryId', ChoiceType::class, [
'mapped' => false,
'choices' => $options['choiceCategory'],
'label' => 'Catégorie'
])
->add('productLib', TextType::class, [
'label' => 'Libellé',
])
->add('Enregister', SubmitType::class)
;
}
And my choiceCategory function :
public function choiceCategory(){
$choices = [];
$categories = $this->getCategory();
foreach ($categories as $categorie) {
$choices[$categorie->getCategorylib()] = $categorie->getCategoryid();
}
return $choices;
}
And finaly my controller :
$product = $this->getDoctrine()
->getRepository('App:DProduct')
->findOneBy(array('slug' => $slug));
...
$form = $this->createForm(productType::class, $product, array('choiceCategory'=>$categoryController->choiceCategory()));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
... Data is well saved ...
}
return $this->render(
'form/meuble.html.twig',
array(
'form' => $form->createView(),
'titlePage' => $titlePage,
'product' => $product
)
);
Does anyone see where is the problem ?
Thanks,
Best regards,
Matthieu
You are using an unmapped field, therefore it won't set any data based on the product you are editing.
You can set the data with de data option
$product = $builder->getData();
...
->add('categoryId', ChoiceType::class, [
'mapped' => false,
'choices' => $options['choiceCategory'],
'label' => 'Catégorie'
'data' => $product->getCategory(),
])
U might be able to use a mapped field and use the EntityType instead of the ChoiceType to build the choices. Notice the choice_label and query_builder options.

How to configure my buildForm for a OneToMany relationship?

I'm trying to make a nested Form, embed a collection of forms inside a form.
i have problem with the buildForm.
I'm trying to add a formType in a other form type in my case to add educations to my CurriculumVitae form.
One CurriculumVitae has Many Educations.
Many Education have One CurriculumVitae.
im getting this error message:
Expected argument of type "array or (\Traversable and \ArrayAccess)",
"string" given
CurriculumVitae Entity:
/**
* CurriculumVitae
*
* #ORM\Table(name="curriculum_vitae")
* #ORM\Entity(repositoryClass="GE\CandidatBundle\Repository\CurriculumVitaeRepository")
*/
class CurriculumVitae
{
/**
* #ORM\OneToMany(targetEntity="GE\CandidatBundle\Entity\Education", mappedBy="curriculumVitae", cascade={"persist", "remove"})
* #ORM\Column(name="id_education")
*/
protected $educations;
/**
* Add education
*
* #param \GE\CandidatBundle\Entity\Education $education
*
* #return CurriculumVitae
*/
public function addEducation(\GE\CandidatBundle\Entity\Education $education)
{
$this->educations[] = $education;
$education->setCurriculumVitae($this);
return $this;
}
/**
* Remove education
*
* #param \GE\CandidatBundle\Entity\Education $education
*/
public function removeEducation(\GE\CandidatBundle\Entity\Education $education)
{
$this->educations->removeElement($education);
}
}
Education Entity:
/**
* Education
*
* #ORM\Table(name="education")
* #ORM\Entity(repositoryClass="GE\CandidatBundle\Repository\EducationRepository")
*/
class Education
{
...
/**
* Many Education have One CurriculumVitae.
* #ORM\ManyToOne(targetEntity="GE\CandidatBundle\Entity\CurriculumVitae", inversedBy="educations")
* #ORM\JoinColumn(name="curriculumVitae_id", referencedColumnName="id")
*/
private $curriculumVitae;
}
CurriculumVitaeType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('educations',
CollectionType::class, [
'entry_type' => EducationType::class,
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
'label' => 'Educations:'
]
)
;
}
CurriculumVitaeController:
class CurriculumVitaeController extends Controller
{
...
public function editAction(Request $request, CurriculumVitae $curriculumVitae)
{
$deleteForm = $this->createDeleteForm($curriculumVitae);
$editForm = $this->createForm('GE\CandidatBundle\Form\CurriculumVitaeType', $curriculumVitae);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('cv_edit', array('id' => $curriculumVitae->getId()));
}
return $this->render('curriculumvitae/edit.html.twig', array(
'curriculumVitae' => $curriculumVitae,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
}
I don't know if it's a problem with the constructor or what?
In my CurriculumVitae Entity:
/**
* Constructor
*/
public function __construct()
{
$this->objectifs = new \Doctrine\Common\Collections\ArrayCollection();
$this->educations = new \Doctrine\Common\Collections\ArrayCollection();
$this->experiences = new \Doctrine\Common\Collections\ArrayCollection();
$this->formations = new \Doctrine\Common\Collections\ArrayCollection();
$this->competences = new \Doctrine\Common\Collections\ArrayCollection();
$this->dateAjout = new \Datetime();
$this->etat = false;
$this->disponibilite = false;
}
May be that the problem is here, when we need to nest a single form more than once i mean with which relationships?
Sorry,
I found my problem.
1) $candidatId should be $candidat. we are not storing ids in the entity but rather a reference to $candidat.
2) There is no column for education ids in CurriculumVitae. The relationship is stored in each individual Education entity.
3) There is no need to #ORM\Column(name="id_education").
and i added a JoinColumn to $idCurriculumVitae
/**
* #var CurriculumVitae
* #ORM\ManyToOne(targetEntity="GE\CandidatBundle\Entity\CurriculumVitae")
*#ORM\JoinColumn(name="curriculumVitae_id",referencedColumnName="id",onDelete="SET NULL")
*/
private $idCurriculumVitae;
I have a many to one related entities and every time I create a new CurriculumVitae entity which is related to Candidat entity the column candidat_id_id is null.
Only the entity CurriculumVitae is successfully created and persisted except the Candidat id in the data datatable.
CurriculumVitae table:
id | titre | candidat_id_id | id_education
candidat_id_id is: null
id_education has this value: Doctrine\Common\Collections\ArrayCollection#000000003d585f990000000052235238
Education table is empty
id | description | id_curriculum_vitae_id
My problem is with the id_curriculum_vitae_id and the id_education.

Notice: Undefined index: roles in Symfony 2.7

I am trying to learn Symfony2 and currently : Entity Relationships/Associations (Joining to Related Records) . I have a problem I can not get correct
Notice: Undefined index: roles 500 Internal Server Error -
ContextErrorException
This is the my code:
*Class Role:
class Roles
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="nom_roles", type="string", length=225, nullable=false)
*#Assert\NotBlank(message="le champ nom du role est obligatoire")
*
*/
Private $name_role;
/**
* #var ArrayCollection $groups
*
* #ORM\OneToMany(targetEntity="Groups", mappedBy="roles", cascade={"persist","merge"})
*#Assert\Valid()
*/
protected $groups;
/**
* #var ArrayCollection Permissions $permision
*
* #ORM\ManyToMany(targetEntity="Permissions", inversedBy="roleGroup", cascade={"persist", "merge"})
* #ORM\JoinTable(name="roles_permissions",
* joinColumns={#ORM\JoinColumn(name="id_rolesGR", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="id_permGR", referencedColumnName="id_per")}
* )
* #Assert\Valid()
*/
protected $permissions_role;
/**
* Roles constructor.
*/
public function __construct()
{
$this->groups = new ArrayCollection();
$this->permissions_role = new ArrayCollection();
}
-class permissions:
class Permissions {
/**
* #var integer
*
* #ORM\Column(name="id_per", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
* #ORM\Column(name="nom_permisions", length=255, nullable=true)
* #Assert\NotBlank(message="le choix des permissions sont obligatoire")
*/
private $name_permissions;
/**
* #var ArrayCollection Roles $roleGroup
*
* Inverse Side
*
* #ORM\ManyToMany(targetEntity="Roles", mappedBy="permissions", cascade={"persist", "merge"})
*#Assert\Valid()
*/
protected $roleGroup;
-Class Groups:
class Groups
{
/**
* #var integer
*
* #ORM\Column(name="id_groupes", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*
*/
private $id;
/**
* #var string
*
*-- contrainte sur le chmap
*
* #Assert\NotBlank(message="le champ nom du groupe est obligatoire")
*
* #Assert\Type(
* type="string",
* message="la valeur {{ value }} n'est pas valide {{ type }}.
* Elle est de type chaine des cractéres"
* )
*
* #Assert\Length(
* min=5,
* max= 50,
* minMessage="votre nom du groupe doit comprendre au moins {{ limit }} caractéres",
* maxMessage="votre nom du groupe doit comprendre au maximun {{ limit }} caractéres"
* )
*
* #ORM\Column(name="nom_groupe", type="string", length=225, nullable=false)
*#Assert\NotBlank(message="le champ nom du groupe est obligatoire")
*
*
*/
Private $name_groups;
/**
* #var DateTime()
*
* #ORM\Column(name="date_creation", type="datetime",nullable=false)
*
*#Assert\DateTime()
*/
private $date_create;
/**
* #ORM\OneToOne(targetEntity="Images", cascade={"persist", "merge", "remove"})
* #ORM\JoinColumn(name="image_id", referencedColumnName="id_images")
* #Assert\Valid()
*/
protected $image;
/**
* #var Roles $role
*
* #ORM\ManyToOne(targetEntity="Roles", inversedBy="groups", cascade={"persist", "merge"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="role_id", referencedColumnName="id", nullable=false)
* })
* #Assert\Valid()
*/
protected $role;
-here is my controller
class GroupsController extends Controller
{ public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('GroupsBundle:Groups')->findAll();
return $this->render('GroupsBundle:Groups:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Creates a new Groups entity.
*
*/
public function createAction(Request $request)
{
$entity = new Groups();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('groups_show', array('id' => $entity->getId())));
}
return $this->render('GroupsBundle:Groups:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a form to create a Groups entity.
*
* #param Groups $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Groups $entity)
{
$form = $this->createForm(new GroupsType(), $entity, array(
'action' => $this->generateUrl('groups_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Groups entity.
*
*/
public function newAction()
{
$entity = new Groups();
$form = $this->createCreateForm($entity);
return $this->render('GroupsBundle:Groups:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Groups entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('GroupsBundle:Groups')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Groups entity.');
}
$deleteForm = $this->createDeleteForm($id);
return $this->render('GroupsBundle:Groups:show.html.twig', array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing Groups entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('GroupsBundle:Groups')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Groups entity.');
}
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('GroupsBundle:Groups:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Creates a form to edit a Groups entity.
*
* #param Groups $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Groups $entity)
{
$form = $this->createForm(new GroupsType(), $entity, array(
'action' => $this->generateUrl('groups_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Groups entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('GroupsBundle:Groups')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Groups entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('groups_edit', array('id' => $id)));
}
return $this->render('GroupsBundle:Groups:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Groups entity.
*
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('GroupsBundle:Groups')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Groups entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('groups'));
}
/**
* Creates a form to delete a Groups entity by id.
*
* #param mixed $id The entity id
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('groups_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Delete'))
->getForm()
;
}
}
the problem:
Catchable Fatal Error: Argument 1 passed to
Doctrine\Common\Collections\ArrayCollection::__construct() must be of
the type array, object given, called in
/home/cros/Desktop/Project_Console/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php
on line 555 and defined 500 Internal Server Error -
ContextErrorException
*Stack Trace:
in vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php at line 48 -
/*
* #param array $elements
*/
public function __construct(array $elements = array())
{
$this->elements = $elements;
}
at ErrorHandler ->handleError ('4096', 'Argument 1 passed to
Doctrine\Common\Collections\ArrayCollection::__construct() must be of
the type array, object given, called in
/home/cros/Desktop/Project_Console/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php
on line 555 and defined',
'/home/Cros/Desktop/Project_Console/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php',
My GroupsType and RolesType:
class GroupsType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('image',new ImagesType())
->add('name_groups', 'text',array('required' => true, 'attr' => array('placeholder' => 'Nom du groupe')))
->add('role', new RolesType())
;
}
}
//My RolesType:
class RolesType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('groups', 'entity',array(
'class' => 'GroupsBundle:Roles',
'choice_label' => 'name_role',
/*'query_builder' => function(EntityRepository $er)
{
return $er->createQueryBuilder('r')
->orderBy('r.id', 'ASC');
},*/
'required' => true,
'placeholder' => 'Choisir le role du votre groupe'
)
)
->add('permissions_role','entity',array(
'class' => 'GroupsBundle:Permissions',
'multiple' => true,
'expanded' => true,
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.id', 'ASC');
},
'required' => true
)
)
// ->add('permissions_role','number')
;
Thank you
It's quite hard to dig through all the code you've supplied here, but I'll try to help.
As I see, the $groups property in your Roles class is annotated with OneToMany having mappedBy set to "roles".
/**
* #var ArrayCollection $groups
*
* #ORM\OneToMany(targetEntity="Groups", mappedBy="roles", cascade={"persist","merge"})
* #Assert\Valid()
*/
protected $groups;
The target entity of the relation is Groups, and as far as I see from your listings, this entity does not have a roles property, it has role instead:
/**
* #var Roles $role
*
* #ORM\ManyToOne(targetEntity="Roles", inversedBy="groups", cascade={"persist", "merge"})
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="role_id", referencedColumnName="id", nullable=false)
* })
* #Assert\Valid()
*/
protected $role;
You should try renaming this property to roles instead.

Delete an item from oneToMany relationship

I have the following Gallery entity
class Gallery
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="Tessa\GalleryBundle\Entity\Photo", mappedBy="gallery", cascade={"persist", "remove"})
*/
private $photos;
/* ... */
}
This gallery is linked with a manyToOne relationship to a PointOfInterest entity. Here is the declaration
class PointOfInterest
{
/* ... */
/**
* #ORM\ManyToOne(targetEntity="Tessa\GalleryBundle\Entity\Gallery", cascade={"persist", "remove"})
* #ORM\JoinColumn(nullable=false)
*/
private $gallery;
/* ... */
I also use a Form to update the PointOfInterest entity. Here is the form declaration
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text')
->add('gallery', new GalleryType())
;
}
and the GalleryType declaration.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('photos', 'collection', array('type' => new PhotoType(),
'required' => false,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
))
;
}
When I edit the PoI I can add photos to the gallery without problem, but I can't delete anything.
I tried to hook on gallery PreUpdate, but it is never called. I printed output in removePhotos method of Gallery entity, and the photos are removed from the gallery. I then suspect the Gallery to never be persisted.
Here is the code when I persist the PoI after editing.
private function handleForm($elem, $is_new)
{
$form = $this->createForm(new CircuitType, $elem);
$request = $this->get('request');
if ($request->getMethod() == 'POST') {
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($elem);
$em->flush();
return $this->redirect($this->generateUrl('tessa_circuit_index'));
}
}
return $this->render('TessaUserBundle:Circuits:add.'.'html'.'.twig',
array(
'form' => $form->createView(),
'is_new' => $is_new,
));
}
There is article in Symfony2 cookbook about handling this type of situation. As you have OneToMany relationship, you have to remove related objects manually in controller.
Edit:
Or you can make use of Doctrine's orphan removal feature.
class Gallery
{
//...
/**
* #ORM\OneToMany(targetEntity="Photo", mappedBy="gallery", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $photos;
//...
public function removePhotos($photo)
{
$this->photos->remove($photo);
$photo->setGallery(null);
}
}

Resources