2017-03-03 1 views
0

두 개의 테이블이 있습니다. 단계와 링크가 1 : n으로 결합되었습니다. 단계 개체를 통해 링크를 유지하려고합니다. 데이터베이스에서 모든 단계를 검색하고 링크 테이블과의 관계를 채 웁니다. JSON에 대한 링크 모음을 포함하는 step 객체를 유지하고 REST를 사용하여 프런트 엔드에 반환합니다.PHP/Propel 레코드 삭제 1 : n

즉, 단계가 프런트 엔드의 다른 단계에 연결되거나 연결 해제되면 전체 단계를 링크 모음을 포함하여 백엔드로 되돌려 보냅니다.

public function put($processStep) { 
     if (isset($processStep['Processesid']) && isset($processStep['Coordx']) && isset($processStep['Coordy'])) { 
      $p = $this->query->findPK($processStep['Id']); 

      $p->setId($processStep['Id']); 
      $p->setProcessesid($processStep['Processesid']); 
      if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']); 
      if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']); 
      $p->setCoordx($processStep['Coordx']); 
      $p->setCoordy($processStep['Coordy']); 

      $links = $p->getLinksRelatedByFromstep(); 
      $links->clear(); 

      foreach ($processStep['Links'] as $link) { 
       if (!isset($link['Linkid'])) { 
        $newLink = new \Link(); 

        $newLink->setFromstep($link['Fromstep']); 
        $newLink->setTostep($link['Tostep']); 

        $links->prepend($newLink); 
       } 
      } 

      $p->save(); 

      return $p; 
     } else { 
      throw new Exceptions\ProcessStepException("Missing mandatory fields.", 1); 
     } 
    } 

나는 기본적으로 단계에서 모든 링크를 삭제하고있어 요청 객체를 기반으로 내가 링크를 다시 : 백 엔드에서 나는 다음과 같은 코드를 사용합니다. 이렇게하면 어떤 링크가 삭제되고 추가되었는지 비교할 필요가 없습니다. 매력 Propel 같은 삽입 작업이 자동으로 새 링크를 만듭니다. 그것은 삽입처럼 삭제되지 않습니다. 유지되고있는 객체 ($ p)를 확인했는데 링크가 삭제 된 것을 볼 수 있지만 MySQL 로그에는 Propel이 수행 한 작업이 전혀 없습니다. 링크 컬렉션에서 누락 된 멤버가 더티 플래그 또는 이와 유사한 것을 트리거하지 않는 것 같습니다.

어쩌면 나는이 잘못된 방향으로 가고 있습니다. 누군가가 조언을 해줄 수 있기를 바랍니다.

감사

+0

것은 내가 돈; 코드에서 anywehere에 대한 호출을 참조하십시오. 나는 단지 당신이 clear()를 사용하는 것을 본다. clear()는 컬렉션에 적용한 기준/필터를 지우지 만 실제로 아무것도 지우지는 않습니다. – chocochaos

+0

$ 링크 변수는 ObjectCollection의 인스턴스입니다. clear 함수는 콜렉션에서 (API 문서에 따라) 단계와 링크 사이의 관계를 깨는 링크를 제거합니다. 적어도 내 추론이었습니다. :) 관계를 끊음으로써 Propel이 컬렉션에 추가 된 링크에 대한 삽입을 트리거하는 것처럼 누락 된 링크 오브젝트에 대한 암시 적 삭제를 트리거하기를 바랬습니다. 명시 적 삭제 호출을 사용하려면 백엔드에 게시 된 링크와 데이터베이스에있는 링크를 비교하기 시작해야합니다. 의견을 보내 주셔서 감사합니다! – Remco

답변

0

Ben에게 감사 드려서 삭제를 명시 적으로 요청하지 않아도됩니다. setRelatedBy (ObjectCollection o)이 함수를 사용하여 관련 객체의 목록을 제공하고 새 객체는 삽입으로 간주되어 누락이 삭제로 해석됩니다.

내가 지금 여기 문제에 관한 모든 관련 문서를 찾을 수 없습니다 내 코드입니다 :

$p = $this->query->findPK($processStep['Id']); 

      $p->setId($processStep['Id']); 
      $p->setProcessesid($processStep['Processesid']); 
      $p->setCoordx($processStep['Coordx']); 
      $p->setCoordy($processStep['Coordy']); 
      if (isset($processStep['Flowid'])) $p->setFlowid($processStep['Flowid']); 
      if (isset($processStep['Applicationid'])) $p->setApplicationid($processStep['Applicationid']); 

      //Get related records, same as populaterelation 
      $currentLinks = $p->getLinksRelatedByFromstep(); 
      $links = new \Propel\Runtime\Collection\ObjectCollection(); 

      //Check for still existing links add to new collection if so. 
      //This is because creating a new Link instance and setting columns marks the object as dirty creating an exception due to duplicate keys 
      foreach ($currentLinks as $currentLink) { 
       foreach ($processStep['Links'] as $link) { 
        if (isset($link['Linkid']) && $currentLink->getLinkid() == $link['Linkid']) { 
         $links->prepend($currentLink); 

         break; 
        } 
       } 
      } 

      //Add new link objects 
      foreach ($processStep['Links'] as $link) { 
       if (!isset($link['Linkid'])) { 
        $newLink = new \Link(); 

        $newLink->setFromstep($link['Fromstep']); 
        $newLink->setTostep($link['Tostep']); 

        $links->prepend($newLink); 
       } 

      } 

      //Replace the collection and save the processstep. 
      $p->setLinksRelatedByFromstep($links); 
      $p->save(); 
1

기록을 삭제하려면, 당신은 절대적으로 항상 delete을 사용해야합니다. 컬렉션의 diff 메서드는 추가, 업데이트 및 삭제해야하는 엔터티를 결정할 때 매우 유용합니다.

+0

감사합니다. 벤, 그게 내가 알아야 할 전부입니다. 수치 스럽지만 삽입과 같은 삭제를 처리하기에 충분히 직관적 이었으면 좋겠다. – Remco