递归Rails嵌套资源

我有一个用于项目管理的Rails应用程序,其中有Project和Task模型。 一个项目可以有很多任务,但任务也可以有很多任务,无限制。

使用嵌套资源,我们可以拥有/ projects / 1 / tasks,/ projects / 1 / tasks / new,/ projects / 1 / tasks / 3 / edit等。

但是,您如何表示RESTful任务的递归性质? 我不想深入到另一个层次,所以可能会有以下情况:

map.resources :tasks do |t| t.resources :tasks end 

这会给我以下url:

 /tasks/3/tasks/new /tasks/3/tasks/45/edit 

或者,当涉及到单个任务时,我可以使用/ tasks / 45 / edit

这是一个合理的设计吗?

凸轮

超越单一嵌套路线的任何地方通常被认为是一个坏主意。

The Rails Way的第108页开始:

Jamis Busk在Rails社区中是一个非常有影响力的人物,几乎与David本人一样。2007年2月,在他的博客中,他基本上告诉我们深度嵌套是一个_bad_事物,并提出了以下经验法则:资源应该永远不会嵌套不止一层。

现在有些人会争论这个问题(在第109页讨论)但是当你谈论用任务嵌套任务时,它似乎没有多大意义。

我会以不同的方式处理你的解决方案,就像上面提到的那样,一个项目应该有很多任务但是对于一项任务来说,许多任务看起来似乎不正确,也许这些任务应该被重新命名为子任务或者其他东西。线。

他们没有理由拥有后代的URL。

逻辑:

 / projects / 1  - >项目1 
 / projects / 1 / edit(etc)
 / tasks / 1  - >任务1 
 / project / 1 / tasks  - >项目1的任务列表 
 /项目/ 1 /任务/新 
 / project / 1 / tasks / 1 / edit  - > / tasks / 5 / edit(redundancy) 
 / project / 1 / tasks / 1  - >重定向到/ tasks / 1 
 / tasks / 1 / project  - >重定向到/ projects / 1 
 / tasks / 3 / tasks  - >作为任务3的子任务的任务列表
 / tasks / 3 / tasks / 5  - > redirect / tasks / 5 /(因为你真的不需要有一个递归的URL)
 / tasks / 5 / parents  - >作为任务父母的任务列表3
 / tasks / 5 / parents / 3  - > redirect / tasks / 3 / 

没有理由恕我直言要求URL是关联的,你不需要知道任务5是任务3的孩子来编辑任务5。

我目前正在做一个类似的项目。 我使用的答案非常优雅,我添加了一个指向另一个任务的parent_id列。 在进行模型时,请确保执行以下操作:

 belongs_to :project belongs_to :parent, :class_name => "Task" has_many :children, :class_name => "Task", :foreign_key => "parent_id" 

…然后你可以通过以下方式进行递归:

 def do_something(task) task.children.each do |child| puts "Something!" do_something(child) end end 

这样,您可以通过其父级或子级引用您的任务。 在进行路线时,您将始终访问单个任务

 /project/:project_id/task/:task_id 

即使它可能有父母或子女。

只要确保你没有一个父项与其子项相同的任务,否则当你进行递归查找所有孩子时,你将进入一个无限循环。 您可以将条件添加到validation脚本中以确保它不会。

另请参见: acts_as_tree