2011-06-23 13 views
8

que estoy tratando de conseguir algo sencillo CRUD hecho con la doctrina 2, pero cuando llega el momento de actualizar un registro con un conjunto de propiedades como una colección de gama No parece que removeElement() funcione como se supone que debe hacerlo. Incluso intenté hacerlo de esta manera ridículamente feo:removeElement() y claro() no funciona en la doctrina 2 con propiedad de colección matriz

foreach($entity->getCountries() as $c) { 
     $entity->getCountries()->removeElement($c); 
     $this->em->persist($entity); 
     $this->em->flush(); 
} 

y no funcionó ... Cualquiera sabe cómo manejar esto? He pedido una solución a esto en muchas formas diferentes y hasta ahora no he obtenido una buena respuesta ... parece que faltan buenos ejemplos del manejo de CRUR de Doctrine 2. Publicaré más código a pedido.

Editar

//in user entity 
/** 
* 
* @param \Doctring\Common\Collections\Collection $property 
* @OneToMany(targetEntity="Countries",mappedBy="user", cascade={"persist", "remove"}) 
*/ 
private $countries; 

//in countries entity 
/** 
* 
* @var User 
* @ManyToOne(targetEntity="User", inversedBy="id") 
* @JoinColumns({ 
* @JoinColumn(name="user_id", referencedColumnName="id") 
* }) 
*/ 
private $user; 
+0

¿Qué es exactamente eres yo tratando de lograr? ¿Estás tratando de eliminar todos los países? ¿O estás tratando de eliminar un país? ¿Has leído la sección sobre Trabajar con asociaciones en los documentos: http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-associations.html#removing-associations – rojoca

+0

sí @rojoca Lo he leído todo. Y estoy tratando de eliminar todos los países asociados a una entidad de usuario, para poder cambiarlos por más países diferentes. –

Respuesta

12

que hacer algo similar en un proyecto con eventos que tienen los participantes no muy diferente de la relación usuario/País. Simplemente estableceré el proceso y podrás ver si hay algo que estás haciendo de manera diferente.

Por Participant entidad

/** 
* @ManyToOne(targetEntity="Event", inversedBy="participants", fetch="LAZY") 
* @JoinColumn(name="event_id", referencedColumnName="id", nullable="TRUE") 
* @var Event 
*/ 
protected $event; 

Por Event entidad:

/** 
* @OneToMany(targetEntity="Participant", mappedBy="event") 
* @var \Doctrine\Common\Collections\ArrayCollection 
*/ 
protected $participants; 

También en Event#__constructor inicializo así:

$this->participants = new \Doctrine\Common\Collections\ArrayCollection(); 

Aquí es cómo puedo actualizar un evento:

public function update(Event $event, Event $changes) 
{ 
    // Remove participants 
    $removed = array(); 
    foreach($event->participants as $participant) 
    { 
     if(!$changes->isAttending($participant->person)) 
     { 
      $removed[] = $participant; 
     } 
    } 

    foreach($removed as $participant) 
    { 
     $event->removeParticipant($participant); 
     $this->em->remove($participant); 
    } 

    // Add new participants 
    foreach($changes->participants as $participant) 
    { 
     if(!$event->isAttending($participant->person)) 
     { 
      $event->addParticipant($participant); 
      $this->em->perist($participant); 
     } 
    } 

    $event->copyFrom($changes); 
    $event->setUpdated(); 
    $this->em->flush(); 
} 

Los métodos de la entidad Event son:

public function removeParticipant(Participant $participant) 
{ 
    $this->participants->removeElement($participant); 
    $participant->unsetEvent(); 
} 

public function addParticipant(Participant $participant) 
{ 
    $participant->setEvent($this); 
    $this->participants[] = $participant; 
} 

Los métodos de la entidad Participant son:

public function setEvent(Event $event) 
{ 
    $this->event = $event; 
} 

public function unsetEvent() 
{ 
    $this->event = null; 
} 

ACTUALIZACIÓN: Método isAttending

/** 
* Checks if the given person is a 
* participant of the event 
* 
* @param Person $person 
* @return boolean 
*/ 
public function isAttending(Person $person) 
{ 
    foreach($this->participants as $participant) 
    { 
     if($participant->person->id == $person->id) 
      return true; 
    } 

    return false; 
} 
+0

Estoy adaptando esto a mi proyecto. Una pregunta rápida sin embargo ... Estoy pasando mi función de actualización una matriz ($ _POST en realidad) ¿cómo se establece el evento y dónde pasarlo como un objeto? Supongo que eso es mucho más "saludable" para la doctrina, ¿verdad? ¿Hay alguna manera de alimentar "automágicamente" el objeto con la matriz? –

+0

Evitaría la creación de objetos "automáticos" a partir de $ _POST. La razón por la que lo hago así es porque la entrada del evento es compleja y requiere mucha validación. Tengo una clase (fábrica) que toma una matriz (por ejemplo, '$ _POST') y crea un objeto' Evento'. Una vez que haya validado ese objeto, puedo guardarlo si es "nuevo", o usarlo para actualizar un evento existente como el anterior. No necesita ir a este extremo si su aporte es simple y solo requiere una validación simple. Solo asegúrate de que siempre valides la entrada. – rojoca

+0

con su ayuda y ejemplo Pude superar mi mayor problema con Doctrine 2, realmente estaba atrapado con esto y ahora mi código incluso se ve más bonito. ¡Muchas gracias! –

1

nueva respuesta

En su entidad de los países, en caso de que no tiene:

@ManyToOne(targetEntity="User", inversedBy="countries") 

en lugar de inversedBy = "id"?

respuesta inicial

Es necesario configurar el campo de los países en su entidad como borrar en cascada. Por ejemplo, en una relación de muchos a bidireccional:

class Entity 
{ 
    /** 
    * 
    * @OneToMany(targetEntity="Country", mappedBy="entity", cascade={"remove"}) 
    */ 
    private $countries; 
} 

esta manera, cuando el ahorro de su entidad, la doctrina también guardará los cambios en las colecciones conectados a su entidad (como los países). De lo contrario, debe eliminar explícitamente los países que desea eliminar antes de la descarga, p.

$this->em()->remove($aCountry); 

Esto también es válido para las operaciones de persistir, fusionar y separar. Más información here.

+0

@faken compruebe la edición, ya está configurada como lo sugirió, sin embargo, no funciona. –

+0

Hola @ la_f0ka, mira mi edición. – faken

+0

@faken, también lo intenté y todavía no parece que se eliminen estos malditos países –

Cuestiones relacionadas