Propel:如何删除通过多对多关系建立的链接

时间:2011-04-28 11:06:05

标签: php symfony1 many-to-many propel

(链接到上一个问题以防万一:Struggling with one-to-many relation in an admin form

我在用户合作伙伴之间的Symfony-1.3 / Propel-1.4项目中有这种多对多的关系。保存用户时,如果某个布尔标志为true,我想清除指向合作伙伴的所有链接。这是我现在所做的,但它不起作用:

// 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,所以我显然错过了一些非常明显的东西。请指出我正确的方向!

编辑:以下是我的工作方式:

将代码移动到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关系。

这就是我需要的。感谢所有参与者。

4 个答案:

答案 0 :(得分:1)

Okey所以现在你有一个多对多关系,在数据库术语中将其实现为三个表(User,Parter和UserPartner)。同样的事情发生在Symfony和Propel上,所以你需要在应该在UserForm中声明的doSave方法做类似的事情:

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

检查应在BaseUser.class.php(lib / model / om / BaseUser.class.php)上声明的方法名称“getUserPartners”

答案 1 :(得分:0)

如果你正在学习Symfony,我建议你使用Doctrine而不是Propel,因为我认为Doctrine比Propel更简单,更“漂亮”。

对于你的问题,我认为你是好方法。如果我是你,我将保留我的功能save()我将在我的模型用户

中编写另一个功能
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 ...

答案 2 :(得分:0)

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

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

有同样的问题。这是一个有效的解决方案。

答案 3 :(得分:0)

问题在于你的第二个解决方案,即。循环遍历相关对象并调用它们上的delete()应该可以工作。这是记录在案的方式(参见:http://www.symfony-project.org/book/1_0/08-Inside-the-Model-Layer#chapter_08_sub_saving_and_deleting_data)。

但是,不是使用删除查询轰炸数据库,您也可以通过向Peer类添加一个使用简单数据库查询执行删除的方法,一次删除它们。