-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.

我忽略了一些微不足道的事情,但我就是想不通。我究竟做错了什么??

4

3 回答 3

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”作为孩子,并且循环继续。

于 2011-04-17T23:51:36.933 回答
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
于 2011-04-17T23:52:22.090 回答
0

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

于 2011-04-17T23:33:21.320 回答