Question

After a long time searching on the web, i decide myself to write my first post. I hope I do it the right way.

Here is my problem. I use symfony 2.1 on my project. And I have to deal with a bi-directionnal Many-to-many relationship Between 2 objects.
I've created the 2 entities, done the mapping, done the controllers, the templates and the formBuilder. I manage to persist both entities. For one entity, i could persist the entity and the relation with the other. But For the other entity, i could only persist the entity. The relation with the other entity do not persist.

Here are extracts of the 2 entities :

class EntrainementCategorie{
{...}

/**  @ORM\ManyToMany(targetEntity="EntrainementType", mappedBy="categories", cascade="persist") */
protected $types;

}

Here is the second entity :

class EntrainementType{

{...}

/** 
 * @ORM\ManyToMany(targetEntity="EntrainementCategorie",inversedBy="types", cascade="persist") 
 * @ORM\JoinTable(name="mottet_entrainement_types_categories",
 *                  joinColumns={@ORM\JoinColumn(name="idType", referencedColumnName="id")},
 *                  inverseJoinColumns={@ORM\JoinColumn(name="idCategorie", referencedColumnName="id")})
 */
protected $categories;

}

So you can see, there is a bidirectionnal Many-to-Many relationship between category and type.

Here are the controllers :

class EntrainementCategorieController extends GenericController{

{...}

public function creerAction(Request $request){
    return $this->creerActionGeneric($request,new Categorie(),new CategorieType());
}

}

The second one :

class EntrainementTypeController extends GenericController{

{...}   

public function creerAction(Request $request){
    return $this->creerActionGeneric($request,new Type(),new TypeType());
}

}

And here is the GenericController :

class GenericController extends Controller{

{...}

protected function creerActionGeneric(Request $request,$object,$objectType){
    $form = $this->createForm($objectType,$object);
    $isThereProblem = false;
    if ($request->isMethod('POST')) {
        $isThereProblem = true;
        $form->bind($request);
        if ($form->isValid()) {
            $this->getEntityManager()->persist($object);
            $this->getEntityManager()->flush();
            $this->get('session')->getFlashBag()->add('information', $this->FORM_SUCCESS_MESSAGE);
            $isThereProblem = false;
        }
    }
    if ($isThereProblem){
        $this->get('session')->getFlashBag()->add('error', $this->FORM_ERROR_MESSAGE);
    }
    return $this->render($this->BUNDLE.':'.$this->ENTITY.':'.$this->CREATE_TEMPLATE, array('form' => $form->createView()));
}

}

Here are the formBuilder :

class EntrainementCategorieType extends AbstractType{

{...}

public function buildForm(FormBuilderInterface $builder, array $options){
    $builder->add('label','text')
            ->add('types','entity',array(
                                    'class' => 'KarateEntrainementBundle:EntrainementType',
                                    'property' => 'label',
                                    'multiple' => true,
                                    'expanded' => true));
}

}

And the second one :

class EntrainementTypeType extends AbstractType{

{...}

public function buildForm(FormBuilderInterface $builder, array $options){
    $builder->add('label','text')
            ->add('categories','entity',array(
                                            'class' => 'KarateEntrainementBundle:EntrainementCategorie',
                                            'property' => 'label',
                                            'multiple' => true,
                                            'expanded' => true));
}

} 

So when i fill the EntrainementType form, both the type and its relations with category are persisted. But when i fille the EntrainementCategory form, only the category is persisted, not its relations with type.

Does anyone knows what am i doing the wrong way ?

Hope i've been clear enought. Thank you for you help !

Was it helpful?

Solution

I finally manage to do it. I can't use the creerActionGeneric on that one. I have to set explicitly the association between category and each type :

$form->bind($request);
if ($form->isValid()) {
   $this->getEntityManager()->persist($categorie);
   foreach($categorie->getTypes() as $type){
      $type->addCategorie($categorie);
      $this->getEntityManager()->persist($type);
   }
   $this->getEntityManager()->flush();
}

And that is working just fine. But I don't know why on the other direction when i persist from the Type, I do not have to do like that ??? oO

OTHER TIPS

There is a better way to go about doing via doctrine configuration of relationship. Doctrine will allow you to specify the join table and colums which reference the relationships.

I actually stumbled upon this answer before deciding to read more into it as this didn't seem appropriate... This is the right way to go about making a relationship like this (and in yml because that's what I prefer), and with my entities obviously (feeds can have/belong-to many lists and lists can have/belong-to many feeds)

Configuration for Feed:

manyToMany:
    providerLists:
        targetEntity: ProviderList
        joinTable:
            name: providerlist_feed
            joinColumns:
                feed_id:
                    referencedColumnName: id
            inverseJoinColumns:
                providerlist_id:
                    referencedColumnName: id

Configuration for list

manyToMany:
    feeds:
        targetEntity: Feed
        joinTable:
            name: providerlist_feed
            joinColumns:
                providerlist_id:
                    referencedColumnName: id
            inverseJoinColumns:
                feed_id:
                    referencedColumnName: id

so with that both entities now own each other, and both will persist the same way :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top