2013-05-26 112 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

它可能會更快,如果你寫簡單的SQL查詢模型中的功能,這樣的事情

$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.' 
)' 
); 

我不知道你的確切DB設計的,所以你可能需要更改SQL代碼,但你會得到主要想法。

+0

其實,你真的給了我一些想法。但是,如果它真的不需要編寫普通的SQL查詢呢,我的代碼是否像if(foreach(if(foreach ...)clear()loaded()...是的,它實際上是關於編碼風格 –