removeElement () и clear () не работают в доктрине 2 со свойством коллекции массивов - PullRequest
8 голосов
/ 24 июня 2011

Я пытаюсь сделать простой CRUD с доктриной 2, но когда пришло время обновить запись с одним свойством, установленным в качестве коллекции массивов, мне кажется, что removeElement () не работает так, как должно.Я даже пытался сделать это таким смехотворно безобразным образом:

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

, и это не сработало ... Кто-нибудь знает, как с этим справиться?Я просил найти решение этой проблемы во многих различных формах и пока не получил хорошего ответа ... кажется, что не хватает хороших примеров обработки Doctrine 2 CRUD.Я отправлю больше кода по запросу.

Редактировать

//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;

Ответы [ 2 ]

12 голосов
/ 24 июня 2011

Я делаю нечто подобное в проекте с событиями, в которых есть участники, не похожие на ваши отношения между пользователем и страной.Я просто изложу процесс, и вы увидите, есть ли что-то, что вы делаете по-другому.

На Participant сущности

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

На Event сущности:

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

Также в Event#__constructor Я инициализирую так:

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

Вот как я обновляю событие:

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();
}

Методы в сущности Eventявляются:

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

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

Методы объекта Participant:

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

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

ОБНОВЛЕНИЕ : метод 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;
}
1 голос
/ 24 июня 2011

Новый ответ

В вашей стране, если у вас нет:

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

вместо inversedBy = "id"?

Первоначальный ответ

Вам необходимо установить поле стран в вашей сущности как удалить каскад.Например, для двунаправленного отношения один ко многим:

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

Таким образом, при сохранении вашей сущности доктрина также сохраняет изменения в коллекциях, привязанных к вашей сущности (например, странам).В противном случае вам придется явно удалить страны, которые вы хотите удалить перед очисткой, например,

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

Это также верно для операций сохранения, объединения и отключения.Больше информации здесь .

...