Propel: how to remove link made via many-to-many relation

谁说我不能喝 提交于 2019-12-10 12:13:19

问题


(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.


回答1:


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:

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)




回答2:


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

With this function, you don't must use a PHP foreach.

But I don't understand what is the attribute StringProperty...




回答3:


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

or

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

Had the same problem. This is a working solution.




回答4:


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.



来源:https://stackoverflow.com/questions/5817601/propel-how-to-remove-link-made-via-many-to-many-relation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!