2011-04-17 58 views
-1

我有一个称为文件夹的模型,充当一棵树。在模型中,我有一个实例方法副本,可以将文件夹从一个地方复制到另一个地方。复制文件夹时,其子文件夹也必须复制。我的递归函数没有结束。我究竟做错了什么?

这是我的代码:

class Folder < ActiveRecord::Base 
    acts_as_tree :order => 'name' 
    before_save :check_for_parent 

    def copy(target_folder) 
    new_folder = self.clone 
    new_folder.parent = target_folder 
    new_folder.save! 

    # Copy sub-folders recursively 
    self.children.each do |folder| 
     folder.copy(new_folder) unless folder == new_folder 
    end 
    end 

    def check_for_parent 
    raise 'Folders must have a parent.' if parent.nil? && name != 'Root folder' 
    end 
end 

现在考虑以下情况:

Root folder-+ 
      | 
     Folder 1-+ 
        | 
       Folder 2-+ 
         | 
         Folder 3 

当我在根文件夹中复制文件夹1,它工作正常。它也适用于我将文件夹1复制到文件夹2中时,但是当我将文件夹1复制到文件夹3时,我最终得到了无限递归。在代码:

f1 = Folder.find_by_name('Folder 1') 
f3 = Folder.find_by_name('Folder 3') 
f1.copy(f3) # Never stops 

此代码将导致:

Root folder-+ 
      | 
     Folder 1-+ 
        | 
       Folder 2-+ 
         | 
         Folder 3-+ 
           | 
          Folder 1-+ 
            | 
            Folder 2-+ 
              | 
             Folder 3-+ 
                | 
               Folder 1-+ 
                 | 
                Folder 2-+ 
                   | 
                  Folder 3-+ 
                    | 
                    Folder 1-+ 
                      | 
                      Etc. 

我忽视的东西微不足道,但我无法弄清楚。我究竟做错了什么??

回答

0

我不得不跟踪我最初复制的文件夹。下面的代码工作。当然,如果有人看到有改进的余地,请告诉我。

def copy(target_folder, originally_copied_folder = nil) 
    new_folder = self.clone 
    new_folder.parent = target_folder 
    new_folder.save! 

    originally_copied_folder = new_folder if originally_copied_folder.nil? 

    # Copy sub-folders recursively 
    self.children.each do |folder| 
     folder.copy(new_folder, originally_copied_folder) unless folder == originally_copied_folder 
    end 
    end 
0

尝试在循环实现递归(即预序递归)之前复制当前文件夹。

+0

你是什么意思?看来我已经在循环之前复制了当前文件夹。 (在方法的前三行)你能给我看一些代码吗?谢谢! – Mischa 2011-04-17 23:43:07

+0

对不起,我的意思是“之后”。 – Marcin 2011-04-17 23:58:24

1

试着改变你的方法的顺序,使其首先到达的叶节点,做你的递归前:

def copy(target_folder) 
    new_folder = self.clone 

    # Copy sub-folders recursively 
    self.children.each do |folder| 
    folder.copy(new_folder) unless folder == new_folder 
    end 

    new_folder.parent = target_folder 
    new_folder.save! 
end 

你的问题是,你被重排根目录下的“文件夹3“文件夹1”开始”。然后你的递归调用运行。当它到达'文件夹3'时,它现在具有'文件夹1'作为孩子,并且循环继续。

+0

谢谢。是的,我已经尝试过,但是在那种情况下,我得到了一个错误,因为'before_save'。应该让我的问题更清楚。 – Mischa 2011-04-17 23:55:59

相关问题