【问题标题】:Recursive Rails Nested Resources递归 Rails 嵌套资源
【发布时间】:2010-09-15 12:12:57
【问题描述】:

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

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

但是,您如何以 REST 方式表示任务的递归性质?我不想再深一层,所以也许以下方法可以:

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

这会给我以下网址:

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

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

这样的设计合理吗?

摄像头

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    在单个嵌套路由之外的任何地方通常被认为是一个坏主意。

    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 页进行了讨论),但是当您谈论将任务与任务嵌套时,它似乎没有多大意义。

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

    【讨论】:

      【解决方案2】:

      没有理由他们应该有旧的 URL。

      逻辑上:

      /projects/1 --> 项目 1 /projects/1/edit(等) /tasks/1 --> 任务 1 /project/1/tasks --> 项目 1 的任务列表 /项目/1/任务/新 /project/1/tasks/1/edit -> /tasks/5/edit(冗余) /project/1/tasks/1 -> 重定向到 /tasks/1 /tasks/1/project -> 重定向到 /projects/1 /tasks/3/tasks --> 作为任务 3 的子任务的任务列表 /tasks/3/tasks/5 -> 重定向 /tasks/5/ (因为您实际上并不需要递归 URL) /tasks/5/parents -> 任务 3 的父任务列表 /tasks/5/parents/3 -> 重定向 /tasks/3/

      恕我直言,没有理由要求 URL 具有关联性,您无需知道任务 5 是任务 3 的子项即可编辑任务 5。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 使用acts_as_tree 也可以,并带来额外的好处。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-05
        • 2012-02-02
        相关资源
        最近更新 更多