2008-10-06 3 views
6

У меня есть приложение Rails для управления проектами, где есть модели Project и Task. У проекта может быть много задач, но задача может также иметь много задач, бесконечно.Рекурсивные рельсы Вложенные ресурсы

Использование вложенных ресурсов, мы можем иметь/проекты/1/задачи,/проекты/1/задачи/новый,/проекты/1/задачи/3/редактировать и т.д.

Однако, как вы представляете рекурсивный характер задач RESTfully? Я не хочу идти еще один уровень глубоко, поэтому, возможно, следующий будет делать:

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

Это дало бы мне по следующим ссылкам:

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

Или, может быть, когда дело доходит до отдельного задания, я могу просто используйте/tasks/45/edit

Это разумный дизайн?

Cam

ответ

3

нет никакой причины, они должны иметь URLS-потомок.

логически:

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

нет никаких причин, IMHO требовать URL, ассоциативными, вы не будете нуждаться, чтобы знать, что задача 5 является потомком задачи 3 для редактирования задачи 5.

6

Выйти за пределы одного вложенного маршрута, как правило, считается плохой идеей.

От страницы 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

Я сейчас в проекте, который делает что-то подобное. Ответ, который я использовал, был очень изящным, так как я добавил столбец 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

+0

с помощью `acts_as_tree` будет работать также, и дать дополнительные преимущества. – 2008-10-06 23:42:13