Foros del Web » Programando para Internet » PHP » Symfony »

[SOLUCIONADO] Guardar un ArrayCollection en la BD

Estas en el tema de Guardar un ArrayCollection en la BD en el foro de Symfony en Foros del Web. Hola, Tengo un pequeño gran problema al guardar un tipo ArrayCollection en la BD con Doctrine. La logica es muy simple, una persona puede tener ...
  #1 (permalink)  
Antiguo 03/04/2013, 09:43
Avatar de fhederico  
Fecha de Ingreso: agosto-2009
Mensajes: 247
Antigüedad: 15 años, 3 meses
Puntos: 23
Pregunta Guardar un ArrayCollection en la BD

Hola,

Tengo un pequeño gran problema al guardar un tipo ArrayCollection en la BD con Doctrine. La logica es muy simple, una persona puede tener muchas suscripciones, por lo tanto la relacion crea una nueva tabla que se llama suscripcionxpersona en donde se guardara el ID de la persona y los ID de las suscripciones que el desee, obviamente el ID de la persona lo saco de la sesion que el posea, aqui dejo el codigo


Tabla Suscripciones:

Código HTML:
Ver original
  1. class Suscripciones
  2. {
  3.     /**
  4.      * @var integer
  5.      *
  6.      * @ORM\Column(name="id", type="integer")
  7.      * @ORM\Id
  8.      * @ORM\GeneratedValue(strategy="AUTO")
  9.      */
  10.     protected $id;
  11.  
  12.     /**
  13.      * @var string
  14.      *
  15.      * @ORM\Column(name="Snombre", type="string", length=255)
  16.      * @Assert\NotNull(message="errores.NotNull")
  17.      * @Assert\Length(min = "1", max = "255", minMessage="errores.length.minMessage", maxMessage="errores.length.maxMessage")
  18.      */
  19.     protected $sNombre;
  20.  
  21.     public function __toString()
  22.     {
  23.         return $this->getSNombre();
  24.     }
  25.  
  26.     /**
  27.      * @ORM\OneToMany(targetEntity="SuscripcionXcandidato", mappedBy="sxcsuscripcionid")
  28.      */
  29.     protected $suscripcionxcandidato;
  30.  
  31.     public function __construct()
  32.     {
  33.         $this->suscripcionxcandidato = new \Doctrine\Common\Collections\ArrayCollection();
  34.     }
  35.  
  36. //getter y setter de nombre y el getter de id
  37.  
  38.  
  39.     /**
  40.      * Add suscripcionxcandidato
  41.      *
  42.      * @param \Acme\PruebaBundle\Entity\SuscripcionXcandidato $suscripcionxcandidato
  43.      * @return Suscripciones
  44.      */
  45.     public function addSuscripcionxcandidato(\Acme\PruebaBundle\Entity\SuscripcionXcandidato $suscripcionxcandidato)
  46.     {
  47.         $this->suscripcionxcandidato[] = $suscripcionxcandidato;
  48.    
  49.         return $this;
  50.     }
  51.  
  52.     /**
  53.      * Remove suscripcionxcandidato
  54.      *
  55.      * @param \Acme\PruebaBundle\Entity\SuscripcionXcandidato $suscripcionxcandidato
  56.      */
  57.     public function removeSuscripcionxcandidato(\Acme\PruebaBundle\Entity\SuscripcionXcandidato $suscripcionxcandidato)
  58.     {
  59.         $this->suscripcionxcandidato->removeElement($suscripcionxcandidato);
  60.     }
  61.  
  62.     /**
  63.      * Get suscripcionxcandidato
  64.      *
  65.      * @return \Doctrine\Common\Collections\Collection
  66.      */
  67.     public function getSuscripcionxcandidato()
  68.     {
  69.         return $this->suscripcionxcandidato;
  70.     }
  71. }

Tabla suscripcionesxpersona:

Código HTML:
Ver original
  1. class SuscripcionXcandidato
  2. {
  3.     /**
  4.      * @var integer
  5.      *
  6.      * @ORM\Column(name="id", type="integer")
  7.      * @ORM\Id
  8.      * @ORM\GeneratedValue(strategy="AUTO")
  9.      */
  10.     protected $id;
  11.    
  12.     /**
  13.      * @ORM\ManyToOne(targetEntity="Candidato", inversedBy="suscripcionxcandidato")
  14.      * @ORM\JoinColumn(name="sxcid", referencedColumnName="id")
  15.      */
  16.     protected $sxcid;
  17.    
  18.     /**
  19.      * @ORM\ManyToOne(targetEntity="Suscripciones", inversedBy="suscripcionxcandidato")
  20.      * @ORM\JoinColumn(name="SXCsuscripcionID", referencedColumnName="id")
  21.      */
  22.     protected $sxcsuscripcionid;
  23.     /**
  24.      * Get id
  25.      *
  26.      * @return integer
  27.      */
  28.     public function getId()
  29.     {
  30.         return $this->id;
  31.     }
  32.  
  33.     /**
  34.      * Set sxcid
  35.      *
  36.      * @param \Acme\PruebaBundle\Entity\Candidato $sxcid
  37.      * @return SuscripcionXcandidato
  38.      */
  39.     public function setSxcid(\Acme\PruebaBundle\Entity\Candidato $sxcid = null)
  40.     {
  41.         $this->sxcid = $sxcid;
  42.    
  43.         return $this;
  44.     }
  45.  
  46.     /**
  47.      * Get sxcid
  48.      *
  49.      * @return \Acme\PruebaBundle\Entity\Candidato
  50.      */
  51.     public function getSxcid()
  52.     {
  53.         return $this->sxcid;
  54.     }
  55.  
  56.     /**
  57.      * Set sxcsuscripcionid
  58.      *
  59.      * @param \Acme\PruebaBundle\Entity\Suscripciones $sxcsuscripcionid
  60.      * @return SuscripcionXcandidato
  61.      */
  62.     public function setSxcsuscripcionid(\Acme\PruebaBundle\Entity\Suscripciones $sxcsuscripcionid = null)
  63.     {
  64.         $this->sxcsuscripcionid = $sxcsuscripcionid;
  65.    
  66.         return $this;
  67.     }
  68.  
  69.     /**
  70.      * Get sxcsuscripcionid
  71.      *
  72.      * @return \Acme\PruebaBundle\Entity\Suscripciones
  73.      */
  74.     public function getSxcsuscripcionid()
  75.     {
  76.         return $this->sxcsuscripcionid;
  77.     }
  78.    
  79.     public function __construct()
  80.     {
  81.         $this->sxcsuscripcionid = new \Doctrine\Common\Collections\ArrayCollection();
  82.     }
  83. }


El formulario Type (SuscripcionXcandidatoType) donde cargo el formulario:


Código HTML:
Ver original
  1. class SuscripcionXcandidatoType extends AbstractType
  2. {
  3.     public function buildForm(FormBuilderInterface $builder, array $options)
  4.     {
  5.         $builder->add('sxcsuscripcionid', 'entity',
  6.             array(
  7.                 'class' => 'AcmePruebaBundle:Suscripciones',
  8.                 'label' => ' ',
  9.                 'expanded' => true,
  10.                 'multiple' => true,
  11.                 'required' => false,
  12.                 'attr' => array('class' => 'div_cvSuscripciones_checkbox'),
  13.                 'query_builder'  => function(EntityRepository $er)
  14.                                     {
  15.                                         return $er  ->createQueryBuilder('s')
  16.                                                     ->where('s.sestado = 1 AND s.stipoid = 1')
  17.                                                     ->orderBy('s.sorden', 'ASC');
  18.                                     }
  19.             )
  20.         );
  21.     }
  22.  
  23.     public function setDefaultOptions(OptionsResolverInterface $resolver)
  24.     {
  25.         $resolver->setDefaults(array(
  26.             'data_class' => 'Acme\PruebaBundle\Entity\SuscripcionXcandidato',
  27.             // una clave única para ayudar generar la ficha secreta
  28.             'intention'       => 'task_item',
  29.         ));
  30.     }
  31.  
  32.     public function getName()
  33.     {
  34.         return 'an_candidato_suscripcionxcandidato';
  35.     }
  36. }


Y el controller:

Código HTML:
Ver original
  1. public function cvSuscripcionesAction()
  2. {
  3.  
  4.     $entity = new SuscripcionXcandidato();
  5. //Creamos el Formulario
  6.         $form   = $this->createForm(new SuscripcionXcandidatoType(), $entity);     
  7.        
  8.         //Variables que se ocupan en algunos casos
  9.         $request = $this->getRequest();    
  10.        
  11.         //Si se envio, verificamos, si no, seteamos un formulario nuevo
  12.         if($request->getMethod() === 'POST')
  13.         {
  14.             $form->bind($request);         
  15.            
  16.             //Si el formulario es valido, y no contiene errores, ingresamos
  17.             if ($form->isValid())
  18.             {
  19.  //Agregamos las suscripciones seleccionadas
  20.                 foreach ($entity->getSxcsuscripcionid() as $suscripcion)
  21.                 {
  22. $suscripcion->addSuscripcionxcandidato($entity);
  23.  
  24. }
  25.  
  26. $em->persist($entity);                 
  27.                 $em->flush();
  28.  
  29. //redireccion
  30.  
  31. }
  32.         }


Me carga los respectivos checkbox donde puedo seleccionar lo que quiero, pero al momento de guardarlos me tira un lindo error :D

Código HTML:
Ver original
  1. Found entity of type Doctrine\Common\Collections\ArrayCollection on association
  2. Acme\PruebaBundle\Entity\SuscripcionXcandidato#sxcsuscripcionid, but expecting Acme\PruebaBundle\Entity\Suscripciones

He buscado info, pero no he podido resolverlo, hay algo que estoy haciendo mal al guardar pero no logro pillar que
  #2 (permalink)  
Antiguo 12/04/2013, 14:45
Avatar de fhederico  
Fecha de Ingreso: agosto-2009
Mensajes: 247
Antigüedad: 15 años, 3 meses
Puntos: 23
Respuesta: Guardar un ArrayCollection en la BD

Bueno, como ya es costumbre me respondo solo...

Lo primero es cambiar en la Entidad "SuscripcionXcandidato", lo teniamos asi

Código HTML:
Ver original
  1. /**
  2.      * Set sxcsuscripcionid
  3.      *
  4.      * @param \Acme\PruebaBundle\Entity\Suscripciones $sxcsuscripcionid
  5.      * @return SuscripcionXcandidato
  6.      */
  7.     public function setSxcsuscripcionid(\Acme\PruebaBundle\Entity\Suscripciones $sxcsuscripcionid = null)
  8.     {
  9.         $this->sxcsuscripcionid = $sxcsuscripcionid;
  10.    
  11.         return $this;
  12.     }

Ya no guardaremos una Entidad, si no que un ArrayCollection

Código HTML:
Ver original
  1. /**
  2.      * Set sxcsuscripcionid
  3.      *
  4.      * @param \Doctrine\Common\Collections\Collection $sxcsuscripcionid
  5.      * @return \Doctrine\Common\Collections\Collection
  6.      */
  7.     public function setSxcsuscripcionid($sxcsuscripcionid)
  8.     {
  9.         $this->sxcsuscripcionid = $sxcsuscripcionid;
  10.    
  11.         return $this;
  12.     }

Y en nuestro controller


Código HTML:
Ver original
  1. use Doctrine\ORM\EntityRepository;
  2.  
  3.  
  4. public function cvSuscripcionesAction()
  5.     {
  6.         $id = $this->getUser()->getid();
  7.            
  8.         $em = $this->getDoctrine()->getManager();
  9.            
  10.         //Traemos las Suscripciones de Candidato (retorna un array normal)
  11.         $datosForm = $em->getRepository('AcmePruebaBundle:SuscripcionXcandidato')->findSuscripcionCandidato($id);
  12.        
  13.         $entity = new SuscripcionXcandidato();
  14.  
  15.         $formSuscripciones = new \Doctrine\Common\Collections\ArrayCollection();
  16.        
  17.             //Buscamos la suscripcion seleccionada y lo agregamos a nuestro ArrayCollection
  18.         foreach($datosForm as $item)
  19.         {
  20.             $suscripciones = $em->getReference('Acme\PruebaBundle\Entity\Suscripciones', $item->getSxcsuscripcionid()->getId());
  21.             $formSuscripciones->add($suscripciones);
  22.         }
  23.        
  24.     //Seteamos el ArrayCollection en nuestra entidad
  25.         $entity->setSxcsuscripcionid($formSuscripciones);
  26.        
  27.         //Creamos el Formulario en el mismo Controller
  28.         $form   = $this->createFormBuilder($entity)
  29.             ->add('sxcsuscripcionid', 'entity',
  30.                 array(
  31.                     'class' => 'AcmePruebaBundle:Suscripciones',
  32.                     'label' => ' ',
  33.                     'expanded' => true,
  34.                     'multiple' => true,
  35.                     'required' => false,
  36.                     'attr' => array('class' => 'div_cvSuscripciones_checkbox')
  37.                 )
  38.             )
  39.             ->getForm()
  40.         ;
  41.        
  42.        
  43.         //Variables que se ocupan en algunos casos
  44.         $request = $this->getRequest();    
  45.        
  46.         //Si se envio, verificamos, si no, seteamos un formulario nuevo
  47.         if($request->getMethod() === 'POST')
  48.         {
  49.             $form->bind($request);         
  50.            
  51.             //Si el formulario es valido, y no contiene errores, ingresamos
  52.             if ($form->isValid())
  53.             {
  54.                 //Removemos las existentes
  55.                 foreach($datosForm as $item) {
  56.                     $em->remove($item);
  57.                 }
  58.                
  59.                 //Agregamos las suscripciones seleccionadas
  60.                 foreach ($entity->getSxcsuscripcionid() as $suscripcion)
  61.                 {
  62.                     $addSuscripcion = new SuscripcionXcandidato();
  63.                     $addSuscripcion->setSxcid($this->getUser());
  64.                     $addSuscripcion->setSxcsuscripcionid($suscripcion);
  65.                     $em->persist($addSuscripcion);
  66.                 }
  67.  
  68.                 $em->flush();
  69.                
  70.                 //Redireccionamos a la siguiente pagina
  71.                 return $this->redirect(...);
  72.             }
  73.         }
  74.  
  75.  
  76.         return $this->render('AcmePruebaBundle:Prueba:suscripciones.html.twig', array(
  77.             'entity' => $entity,
  78.             'form'   => $form->createView()
  79.         ));    
  80.     }

Eso...

Última edición por fhederico; 15/04/2013 a las 16:57

Etiquetas: bd
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:50.