Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

formulario many-to-many self-reference

24 de octubre de 2017

Hola deseo que los artículos de mi base de datos puedan estar relacionados entre ellos. El problema es que cuando voy a grabar artículos relacionados (que ya existen en la base de datos), me los quiere volver a grabar de nuevas con "INSERT INTO..." en la misma tabla de artículos.

¿Donde esta el error? Gracias de antemano

Os dejo código: Entidad Content.php (la que guarda los artículos)

class Content{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * */
    protected $id;
....
 
    /**
     * Many Contents have Many Contents.
     * @ORM\ManyToMany(targetEntity="Content", mappedBy="related", cascade={"all"}) 
     */
    protected $relatedWithMe;   
    /**
     * Many Contents have many Contents.
     * @ORM\ManyToMany(targetEntity="Content", inversedBy="relatedWithMe", cascade={"all"})
     * @ORM\JoinTable(name="content_related",
     *      joinColumns={@ORM\JoinColumn(name="content_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="content_related_id", referencedColumnName="id")}
     *      )
     */
    protected $related; 
...
 
    public function __construct() {     
        $this->relatedWithMe = new ArrayCollection();
        $this->related = new ArrayCollection();
    }   
...
 
    public function addRelated($content){
        $content->relatedWithMe[] = $this;
        $this->related[] = $content;
    }
    public function removeRelated($content){
        $this->related->removeElement($content);
    }
...
}

ContentType.php

...
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
 
class ContentType extends AbstractType
{   
    public function buildForm(FormBuilderInterface $builder, array $options){
        $builder
            ->add('id',HiddenType::class)
...
            ->add('related', CollectionType::class, array(
                    'entry_type'=>RelatedType::class,
                    'entry_options'=>array('entity_manager'=>$options['entity_manager']),
                    'allow_add'=>true,
                    'allow_delete'=>true,
                    'label' => false,
            ));
...
}
    public function configureOptions(OptionsResolver $resolver) {
            $resolver->setDefaults(array(
                'data_class' => Content::class,
            ));
            $resolver->setRequired(array('entity_manager'));
    }
    public function getBlockPrefix(){
        return 'content';
    }
}

RelatedType.php

...
class RelatedType extends AbstractType
{   
    public function buildForm(FormBuilderInterface $builder, array $options){       
        $builder
            ->add('id',HiddenType::class)
            ->add('title',TextType::class,array('label'=>false,'attr'=>array('class'=>'autocomplete_title','placeholder'=>'título')));
//        $builder->get('id')->addModelTransformer(new DataTransformer\ContentToIdTransformer($options['entity_manager']));
 
/*        $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
            $content = $event->getData();
            die(var_dump($content));
        });*/
    }
    public function configureOptions(OptionsResolver $resolver){
        $resolver->setDefaults(array(
                        'compound' => true,
                        'data_class' => Content::class,
        ));
        $resolver->setRequired(array('entity_manager'));
    }
    public function getParent(){
        return HiddenType::class;
    }
    public function getName(){
        return 'related';
    }
}

Respuestas

#1

No sé si será muy ortodoxo pero de momento lo he solucionado en el Controller:

...
    /**
    * @Route("/extranet/updateContent/{id}",
    *           name = "updateContent" )
    * @Method({"GET", "POST"})
    */
    public function updateContentAction(Request $request, Content $content=null){
                $em = $this->getDoctrine()->getManager();
                if($content==null){
                    $content = new Content;
                    $content->setUser($this->getUser()); 
                }
                $form = $this->createForm('AppBundle\Form\ContentType',$content,array('entity_manager'=>$em));
                $form->handleRequest($request);
                if ($form->isSubmitted() && $form->isValid()) {
/* normalizo la entrada de contenidos relacionados */
                    foreach($content->getRelated() as $related){
                        $idRelated = $related->getId();
                        $content->removeRelated($related);
                        $content->addRelated($em->getRepository('AppBundle:Content')->find($idRelated));
                    }
                    $em->persist($content);
                    $em->flush();
                    $this->addFlash('result','OK');
                }
...
       }

@espantaperros_

25 octubre 2017, 8:38