Propel: как удалить ссылку, сделанную через отношение «многие ко многим»

(ссылка на предыдущий вопрос на всякий случай: Борьба с отношением «один ко многим» в форме администратора )

У меня есть отношение «многие ко многим» в моем проекте Symfony-1.3 / Propel-1.4 между пользователем и партнером . Когда Пользователь сохраняется, если он имеет определенный логический флаг, который является истинным, я хочу очистить все ссылки к партнерам. Вот что я делаю в данный момент, и это не работает:

// inside the User model class public function save(PropelPDO $con = null) { if ($this->getIsBlaBla()) { $this->setStringProperty(NULL); $this->clearUserPartners(); } parent::save($con); } 

Установка свойства string в NULL; взгляд на БД ясно показывает это. Тем не менее, таблица USER_PARTNER по-прежнему поддерживает отношения между пользователями и партнерами. Поэтому я решил, что мне нужно очистить ссылки один за другим, вот так:

 foreach($this->getUserPartners() as $user_partner) { $user_partner->delete(); //UserPartnerPeer::doDelete($user_partner); // tried that too } 

Оба не делают трюк.

Как я уже упоминал в своем предыдущем вопросе, я просто изучаю обезьяну Symfony с помощью проб и ошибок, поэтому я, очевидно, пропущу что-то очень очевидное. Пожалуйста, указывайте мне в правильном направлении!

EDIT: Вот как я сделал это работу:

Переместил код в класс Form, например:

 public function doSave(PropelPDO $con = null) { parent::doSave($con); if ($this->getObject()->getIsSiteOwner()) { $this->getObject()->setType(NULL); $this->getObject()->save(); foreach($this->getObject()->getUserPartners() as $user_partner) { $user_partner->delete(); } } return $this->getObject(); } public function updateObject($values = null) { $obj = parent::updateObject($values); if ($obj->getIsSiteOwner()) { $obj->clearUserPartners(); } return $this->object; } 

Что это делает:

  • Когда логический флаг `is_site_owner` встает, он очищает поле` type` и ** сохраняет объект ** (стыдно, что я так долго не думал об этом).
  • Удаляет все существующие объекты ссылок «много-ко-многим» UserPartner.
  • Очищает недавно связанные (через DoubleList) отношения UserPartner.

Это то, что мне нужно. Спасибо всем, кто принимал участие.

Solutions Collecting From Web of "Propel: как удалить ссылку, сделанную через отношение «многие ко многим»"

Okey, так что теперь у вас есть отношение «многие ко многим», где в терминах базы данных реализовано три таблицы (User, Parter и UserPartner). То же самое происходит с Symfony и Propel, поэтому вам нужно сделать что-то подобное в методе doSave, который должен объявляться в UserForm:

 public function doSave($con = null) { parent::doSave($con); //First all that's good and nice from propel if ($this->getValue('please_errase_my_partners_field')) { foreach($this->getObject()->getUserPartners() as $user_partner_relation) { $user_partner_relation->delete(); } } return $this->getObject(); } 

Проверьте имя метода «getUserPartners», которое должно быть объявлено на BaseUser.class.php (lib / model / om / BaseUser.class.php)

Если вы изучаете Symfony, я предлагаю использовать Doctrine вместо Propel, потому что, я думаю, что Doctrine проще и «красивее», чем Propel.

Для вашей проблемы, я думаю, вы на хорошем пути. Если бы я был вами, я сохраню свою функцию save() Я напишу еще одну функцию в моей модели User

 public function clearUserPartners(){ // You have to convert this query to Propel query (I'm sorry, but I don't know the right syntax) "DELETE FROM `USER_PARTNER` WHERE user_id = '$this->id'" } 

С помощью этой функции вы не должны использовать PHP foreach.

Но я не понимаю, что такое атрибут StringProperty

 UserPartnerQuery::create()->filterByUser( $userObject )->delete(); 

или

 UserPartnerQuery::create()->filterByUser( $partnerObject )->delete(); 

Имела та же проблема. Это рабочее решение.

Дело в том, что ваше второе решение, т.е. цикл над связанными объектами и вызов delete () на них должны работать. Это документированный способ делать вещи (см .: http://www.symfony-project.org/book/1_0/08-Inside-the-Model-Layer#chapter_08_sub_saving_and_deleting_data ).

Но вместо того, чтобы бомбить DB с помощью запросов на удаление, вы могли бы просто удалить их за один раз, добавив метод в ваш класс Peer, который выполняет удаление, используя простой запрос БД.