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);
}
将字符串属性设置为 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 关系。
这就是我需要的。感谢所有参与的人。
(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. When the User is being saved, if it has certain boolean flag being true, I want to clear all the links to the partners. 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; looking at the DB clearly shows it. Thing is however, the USER_PARTNER table still holds the relations between the users and the partners. 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. Please point me in the right direction!
EDIT: Here is how I made it work:
Moved the code to the Form class, like so:
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).
- Removes all existing UserPartner many-to-many link objects.
- Clears newly associated (via the DoubleList) UserPartner relations.
Which is what I need. Thanks to all who participated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
好吧,现在您已经有了一个多对多关系,在数据库术语中,它被实现为三个表(User、Parter 和 UserPartner)。 Symfony 和 Propel 上也会发生同样的情况,因此您需要在应该在 UserForm 中声明的 doSave 方法上执行类似的操作:
检查应该在 BaseUser.class.php (lib/model/om) 上声明的方法名称“getUserPartners” /BaseUser.class.php)
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:
Check the method name "getUserPartners" that should be declared on the BaseUser.class.php (lib/model/om/BaseUser.class.php)
如果你正在学习 Symfony,我建议你使用 Doctrine 而不是 Propel,因为我认为 Doctrine 比 Propel 更简单、更“美丽”。
对于你的问题,我认为你的方法很好。如果我是你,我将保留我的函数
save()
我将在我的模型 User 中编写另一个函数使用此函数,你不必使用 PHP foreach。
但我不明白属性
StringProperty
是什么...If you are learning Symfony, I suggest you use Doctrine instead of Propel because, I think Doctrine is simplier and more "beautiful" than 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 UserWith this function, you don't must use a PHP foreach.
But I don't understand what is the attribute
StringProperty
...或
有同样的问题。这是一个可行的解决方案。
or
Had the same problem. This is a working solution.
问题是你的第二个解决方案,即。循环遍历相关对象并对它们调用 delete() 应该可以。这是有记录的做事方式(请参阅:http://www.symfony-project.org/book/1_0/08-Inside-the-Model-Layer#chapter_08_sub_ saving_and_deleting_data)。
但是,您不必使用删除查询轰炸数据库,而是可以通过向 Peer 类添加一种方法来一次性删除它们,该方法使用简单的数据库查询来执行删除。
The thing is that your second solution, ie. looping over the related objects and calling delete() on them should work. 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).
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.