0

让我们总结一下我想问的问题。

我有一个类别表和一个新闻表。

所以一个类别可以有许多新闻以及子类别。如果我删除一个类别,代码需要找到该类别的子类别以及与该类别相关的新闻,以及要删除的子类别。目前我的代码看起来像这样(目前运行良好):

关系:

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 条相关新闻。我不知道,但我认为这需要一整天才能完成任务。

那么,有人可以提示我以正确的方式完成此代码:如何减少代码?如何减少循环?在这种情况下是否可以创建一个可重用的函数,例如,如果新闻有很多标签,我们会在这里做同样的事情,然后调用那个方法就可以了?

请帮我解决一下这个。如果你不回答,也请给我一个你不回答的理由,以便我提出更有意义的问题。

谢谢

4

2 回答 2

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

我不确定您的确切数据库设计,因此您可能需要更改 SQL 代码,但您了解主要思想。

于 2013-05-26T18:08:57.420 回答
0

假设您正在使用 InnoDB(很可能)。由于外键约束,您不需要任何 PHP 代码。

那里有很多教程,解决方案是使用

ON UPDATE CASCADE
ON DELETE CASCADE

创建父级的外键时。当您更新父级时,所有外键也将被更新(如果需要,通常在 id 更改时),同样如果您删除父级,所有子级也将被删除。

于 2013-05-26T18:01:18.430 回答