【问题标题】:Propel: how to remove link made via many-to-many relationPropel:如何删除通过多对多关系建立的链接
【发布时间】:2011-04-28 11:06:04
【问题描述】:

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

在我的 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);
}

将字符串属性设置为 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 关系。

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

【问题讨论】:

    标签: php symfony1 many-to-many propel


    【解决方案1】:

    好的,所以现在您有一个多对多关系,其中在数据库术语中实现为三个表(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”

    【讨论】:

    • 感谢您的建议。可悲的是,虽然这个方法根本没有被调用。做了一个实验,无论在表单中单击什么,都直接将给定属性置空,但显然这是错误的触摸位置。 :( 必须补充一下,真正的项目实际上使用了 sfGuardPlugin,而我的“用户”模型实际上是那里的“sfGuardUser”,但到目前为止这还不是问题。
    • 嗯,我不知道这是否完全正确,我肯定会调用该方法,因为我过去曾使用过它。由于关系的存储方式,无效化不起作用。把这个推给我!检查位于缓存中的 action.class.php 中生成的 processForm 方法
    • 我确实看过,没有注意到我的代码在这个方法中的任何痕迹。删除了所有缓存,重新生成了所有模型/过滤器/表单,重新部署,重新启动了 Apache,还是一样。要么根本不调用 doSave,要么在对象中对对象所做的更改不会传播到数据库。救命!
    • 好吧,我在尝试的时候显然搞砸了。这次奏效了。剩下最后一件事。我还想在“if”块中清空一个字符串字段:$this->getObject()->setType(NULL); 不过它不会被清除。想法?无论如何都会标记你的答案,但这仍然是一个不错的奖励。
    • 在问题中添加了 EDIT 部分。查看更多详情。
    【解决方案2】:

    如果你正在学习 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的属性是什么...

    【讨论】:

    • 嗯,在我的场景中,它是一个“TYPE”=>“$this->setType(NULL)”。这样写只是为了表明将字符串归零有效,而清除多对多关系则无效。
    • 我不认为“更简单和更漂亮”是在.orms 之间做出选择有什么好处。我自己为我的项目使用 Propel,结果证明它非常简单。我确实支持 Doctrine 算法,因为它是一种更面向对象的 ORM 方法。
    【解决方案3】:
    UserPartnerQuery::create()->filterByUser( $userObject )->delete();
    

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

    遇到了同样的问题。这是一个可行的解决方案。

    【讨论】:

    • 会不会是 *Query 类是在 propel 1.5 版本中添加的?
    • 如果是这样,我就没有运气了。在这个项目中使用 Propel 1.4。
    【解决方案4】:

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

    但是,与其用删除查询轰炸数据库,不如一次性删除它们,方法是向 Peer 类添加一个使用简单数据库查询执行删除的方法。

    【讨论】:

    • 正如我所提到的,这里仍然是 Symfony 的新手。感谢您提供一些可以做到这一点的代码 sn-p。我确信我可以自己发明它,但如果我有示例代码,我会更有信心进行实验。
    猜你喜欢
    • 1970-01-01
    • 2011-08-04
    • 2011-11-29
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多