我的递归函数没有结束。我做错了什么?
我有一个名为文件夹的模型,它充当一棵树。在模型内部,我有一个实例方法 copy,它将文件夹从一个地方复制到另一个地方。复制文件夹时,其子文件夹也必须复制。
这是我的代码:
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.
我忽略了一些微不足道的事情,但我就是无法弄清楚。我做错了什么?
I have a model called folder that acts as a tree. Inside the model I have an instance method copy that copies folders from one place to another. When copying a folder, its sub-folders also have to be copied.
This is my code:
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
Now consider the following situation:
Root folder-+
|
Folder 1-+
|
Folder 2-+
|
Folder 3
When I copy Folder 1 in the root folder it works fine. It also works when I copy Folder 1 into Folder 2, but when I copy Folder 1 into Folder 3 I end up with endless recursion. In code:
f1 = Folder.find_by_name('Folder 1')
f3 = Folder.find_by_name('Folder 3')
f1.copy(f3) # Never stops
This code leads to:
Root folder-+
|
Folder 1-+
|
Folder 2-+
|
Folder 3-+
|
Folder 1-+
|
Folder 2-+
|
Folder 3-+
|
Folder 1-+
|
Folder 2-+
|
Folder 3-+
|
Folder 1-+
|
Etc.
I am overlooking something trivial but I just can't figure it out. What am I doing wrong??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尝试更改方法的顺序,以便在执行递归之前它首先到达叶节点:
您的问题是您首先将“文件夹 1”重新设置为“文件夹 3”下的父级。然后你的递归调用就会运行。当到达“文件夹 3”时,它现在将“文件夹 1”作为子项,并且循环继续。
Try changing the order of your method so that it reaches the leaf node first, before doing your recursion:
Your problem is that you're starting by reparenting 'Folder 1' under 'Folder 3'. Then your recursive call runs. When it gets to 'Folder 3' it now has 'Folder 1' as a child, and the cycle continues.
尝试在实现递归(即前序递归)的循环之前复制当前文件夹。
Try doing the copying of the current folder before loop that implements the recursion (i.e. pre-order recursion).
我必须跟踪我最初复制的文件夹。下面的代码有效。当然,如果有人认为有改进的空间,请告诉我。
I had to keep track of which folder I originally copied. The code below works. Of course, if anyone sees room for improvement, please let me know.