简体   繁体   English

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

[英]Propel: how to remove link made via many-to-many relation

(link to previous question just in case: Struggling with one-to-many relation in an admin form ) (链接到上一个问题以防万一: 在管理表单中处理一对多关系

I have this many-to-many relation in my Symfony-1.3 / Propel-1.4 project between User and Partner .我在我的 Symfony-1.3 / Propel-1.4 项目中UserPartner之间有这种多对多的关系。 When the User is being saved, if it has certain boolean flag being true, I want to clear all the links to the partners.保存用户时,如果某个 boolean 标志为真,我想清除所有与合作伙伴的链接。 Here is what I do at the moment and it doesn't work:这是我目前所做的,但它不起作用:

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

Setting the string property to NULL works;将字符串属性设置为 NULL 有效; looking at the DB clearly shows it.查看数据库清楚地表明了这一点。 Thing is however, the USER_PARTNER table still holds the relations between the users and the partners.但是,USER_PARTNER 表仍然保存着用户和合作伙伴之间的关系。 So I figured I have to clear the links one by one, like this:所以我想我必须一一清除链接,如下所示:

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

Both don't do the trick.两者都不做伎俩。

As I mentioned in my previous question, I am just monkey-learning Symfony via trial and error, so I evidently miss something very obvious.正如我在上一个问题中提到的,我只是通过反复试验来猴子学习 Symfony,所以我显然错过了一些非常明显的东西。 Please point me in the right direction!请指出我正确的方向!

EDIT: Here is how I made it work:编辑:这是我如何使它工作的:

Moved the code to the Form class, like so:将代码移至表格 class,如下所示:

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

What this does is:这是做什么的:

  • When the boolean flag `is_site_owner` is up, it clear the `type` field and **saves** the object (ashamed I have not figured that out for so long).当 boolean 标志 `is_site_owner` 为 up 时,它会清除 `type` 字段并**保存** object(很惭愧我这么久都没想到)。
  • Removes all existing UserPartner many-to-many link objects.删除所有现有的 UserPartner 多对多链接对象。
  • Clears newly associated (via the DoubleList) UserPartner relations.清除新关联的(通过 DoubleList)UserPartner 关系。

Which is what I need.这就是我需要的。 Thanks to all who participated.感谢所有参与了的人。

Okey so now you have a many-to-many relation where in database terms is implemented into three tables (User, Parter and UserPartner).好的,所以现在您有一个多对多关系,其中在数据库术语中实现为三个表(用户、合作伙伴和用户合作伙伴)。 Same thing happens on Symfony and Propel, so you need to do something like this on the doSave method that should declare in UserForm:同样的事情发生在 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();
}

Check the method name "getUserPartners" that should be declared on the BaseUser.class.php (lib/model/om/BaseUser.class.php)检查应在 BaseUser.class.php (lib/model/om/BaseUser.class.php) 上声明的方法名称“getUserPartners”

If you are learning Symfony, I suggest you use Doctrine instead of Propel because, I think Doctrine is simplier and more "beautiful" than Propel.如果您正在学习 Symfony,我建议您使用 Doctrine 而不是 Propel,因为我认为 Doctrine 比 Propel 更简单,更“漂亮”。

For your problem, I think you are on the good way.对于您的问题,我认为您正在走上正轨。 If I were you, I will keep my function save() I will write an other function in my model User如果我是你,我会保留我的 function save()我会在我的 model 用户中写另一个 function

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'"
}

With this function, you don't must use a PHP foreach.使用此 function,您不必使用 PHP foreach。

But I don't understand what is the attribute StringProperty ...但我不明白StringProperty的属性是什么......

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

or或者

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

Had the same problem.有同样的问题。 This is a working solution.这是一个可行的解决方案。

The thing is that your second solution, ie.问题是您的第二个解决方案,即。 looping over the related objects and calling delete() on them should work.遍历相关对象并在它们上调用 delete() 应该可以工作。 It's the documented way of doing things (see: http://www.symfony-project.org/book/1_0/08-Inside-the-Model-Layer#chapter_08_sub_saving_and_deleting_data ).这是记录在案的做事方式(参见: http://www.symfony-project.org/book/1_0/08-Inside-the-Model-Layer#chapter_08_sub_saving_and_deleting_data )。

But instead of bombing the DB with delete queries, you could just as well delete them in one go, by adding a method to your Peer class that performs the deletion using a simple DB query.但是,与其用删除查询轰炸数据库,不如在一个 go 中删除它们,方法是向您的对等 class 添加一个方法,该方法使用简单的数据库查询执行删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM