递归Rails嵌套资源

时间:2008-10-06 13:05:37

标签: ruby-on-rails ruby

我有一个用于项目管理的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

这会给我以下网址:

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

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

这是一个合理的设计吗?

凸轮

3 个答案:

答案 0 :(得分:6)

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

来自 The Rails Way 的第108页

"Jamis Busk a very influential figure in the Rails community, almost as much as David himself. In February 2007, vis his blog, he basically told us that deep nesting was a _bad_ thing, and proposed the following rule of thumb: Resources should never be nested more than one level deep."

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

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

答案 1 :(得分:3)

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

逻辑:

/projects/1  --> project 1 
/projects/1/edit ( etc )
/tasks/1     --> task 1 
/project/1/tasks --> task list for project 1 
/project/1/tasks/new 
/project/1/tasks/1/edit ->  /tasks/5/edit ( redundancy ) 
/project/1/tasks/1 -> redirect to /tasks/1 
/tasks/1/project -> redirect to /projects/1 
/tasks/3/tasks --> list of tasks that are children tasks of task 3
/tasks/3/tasks/5 -> redirect /tasks/5/    ( because you don't really need to have a recursive URL )
/tasks/5/parents -> list of tasks that are parents of tasks 3
/tasks/5/parents/3 -> redirect /tasks/3/ 

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

答案 2 :(得分:2)

我目前正在开展一个类似的项目。我使用的答案非常优雅,我添加了一个指向另一个任务的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

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

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

另请参阅:acts_as_tree