2013-05-26 2 views
0

내가 물어보고 싶은 것을 요약 해 보겠습니다.Kohana 3.2 ORM 질문

나는 카테고리 테이블과 뉴스 테이블을 가지고 있습니다.

그래서 카테고리에는 많은 뉴스와 하위 카테고리가있을 수 있습니다. 카테고리를 삭제하면 해당 카테고리와 관련된 뉴스뿐만 아니라 카테고리의 하위 카테고리도 찾아야하며 하위 카테고리도 삭제해야합니다. 현재 내 코드 (그것은 순간에 잘 작동) 그래서 다음과 같습니다

의 관계 :

public $_has_many = array(
     'news' => array(
      'model'   => 'news', 
      'foreign_key' => 'cat_id' 
     ) 
    ); 

코드를 삭제 :

/* 
    * @param $ids: The array of category id that we want to delete 
    */ 
    public function delete_items($ids){ 

     if(!is_array($ids)) 
      $ids = array($ids); 

     if(is_array($ids)){ 
      $recursive = new System_Recursive(); 
      /* 
      * list_items() method will simply return all records for the category table 
      */ 
      $source = $this->list_items(null); 

      /* 
      * Loop through the category ids 
      */ 
      foreach($ids as $id){ 

       $result = $this->where('id', '=', $id)->find(); 
       if($result->loaded()){ 

        // If category found, then find all the news related to that category 
        $main_category_news = $result->news->find_all(); 
        if($main_category_news){ 
         // Loop through all the news and proccess the delete method 
         foreach($main_category_news as $main_news){ 
          $main_news->delete(); 
         } 
        } 

        /* 
        * The find_children() method returns all sub categories of the current category ($result) 
        */ 
        $recursive->find_children($source, $result->id, $arr_children, false); 

        if($arr_children){ 
         // If any sub categories found, continue to loop :((, terrible 
         foreach($arr_children as $child){ 
          $this->clear(); 
          $child_result = $this->where('id', '=', $child)->find(); 
          if($child_result->loaded()){ 
           /* 
           * Again, find news related to this sub category and then loop through the news to do single delete 
           */ 
           $child_news = $child_result->news->find_all(); 
           foreach($child_news as $c){ 
            $c->delete(); 
           } 
          } 
          /* 
          * After deleting news for sub category, 
          * I use clear to prevent error from loaded object 
          * Then find "again" the sub category to delete it 
          */ 
          $this->clear(); 
          $child_delete = $this->where('id','=',$child)->find(); 
          if($child_delete->loaded()){ 
           $child_delete->delete(); 
          } 
         } 
        } 

        /* 
        * And finally for the main direct category 
        */ 
        $this->clear(); 
        $result = $this->where('id', '=', $id)->find(); 
        $result->delete(); 
       } 
      } 
     } 

코드에 많은 많은 루프가 있습니다 50 개 카테고리에서 약 5 개 카테고리를 삭제하고 각 카테고리와 관련된 500 개의 뉴스를 삭제 해 보겠습니다. 나는 모른다.하지만이 일을 끝내기 위해 하루 종일 걸릴 것이라고 생각한다.

그럼, 누군가가 나에게 올바른 방법으로이 코드를 작성하는 힌트를 줄 수 있습니까? 코드를 줄이는 방법은 무엇입니까? 루프를 줄이는 방법? 이 경우 재사용 할 수있는 함수를 만들 수 있습니까? 예를 들어 뉴스에 태그가 많은 경우 여기에서 동일한 작업을 수행하고 해당 메서드를 호출하면 좋은 것입니다.

도와주세요. 당신이 대답하지 않는다면, 왜 당신이하지 않는지에 대한 이유를 알려주십시오. 그래서 나는 더 의미있는 질문을 할 수 있습니다.

고맙습니다.

답변

0

InnoDB를 사용한다고 가정 해 봅시다. foreign key constraints 덕분에 PHP 코드가 필요 없습니다.

는 부모의 외래 키를 생성 할 때이 솔루션은

ON UPDATE CASCADE 
ON DELETE CASCADE 

을 사용하고, 거기에 자습서 많이 있습니다. 부모를 업데이트하면 모든 외래 키들도 업데이트됩니다 (필요한 경우 대개 ID가 변경 될 때). 또한 부모를 삭제하면 모든 자식도 삭제됩니다.

+0

감사합니다. 그러나 MyISAM을 사용하고 있습니다. –

1

당신이 당신의 모델 기능에 내가 정확한 DB 설계 모르겠어요이

$query = DB::query(Database::DELETE, 'DELETE FROM news WHERE news.id IN 
(
SELECT news.id FROM news 
JOIN sub_category ON news.sub_category_id = sub_category.id 
JOIN category ON sub_category.category_id = category.id 
WHERE category.id = '.$this->id.' 
)' 
); 

같은 것을 일반 SQL 쿼리를 작성하는 경우 그것은 더 빨리 될 수 있습니다, 그래서 당신은 SQL 코드를 변경해야 할 수도 있지만, 당신은 주요 아이디어를 얻습니다.

+0

사실, 당신은 정말로 저에게 몇 가지 아이디어를주었습니다. 하지만 실제로 SQL 쿼리를 작성하지 않으면 어떻게됩니까? (foreach (if foreach ... clear()) loaded() ... 예, 코딩 스타일에 관한 것입니다. –