2008-10-06 10 views
6

Tengo una aplicación Rails para la gestión de proyectos donde hay modelos de proyectos y tareas. Un proyecto puede tener muchas tareas, pero una tarea también puede tener muchas tareas, ad infinitum.Recursive Rails Nested Resources

El uso de los recursos anidados, podemos tener/proyectos/1/tareas,/proyectos/1/tareas/nueva,/proyectos/1/tareas/3/editar etc.

Sin embargo, ¿cómo se representa la naturaleza recursiva de las tareas ¿RESTfully? No quiero ir a otro nivel de profundidad, por lo que tal vez el siguiente haría:

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

que me daría las siguientes direcciones:

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

O tal vez cuando se trata de una tarea individual que puedo solo use/tasks/45/edit

¿Es este un diseño razonable?

Cam

Respuesta

3

no hay ninguna razón por la que deben tener las URL decendant.

lógicamente:

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

no hay razón para requerir mi humilde opinión las URLs sean asociativo, usted no va a necesitar saber que la tarea 5 es un niño de 3 tarea de editar la tarea 5.

6

Ir más allá de una ruta anidada única generalmente se considera una mala idea.

Desde la página 108 de Los Carriles Camino:

"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."

Ahora se podría argumentar con esto (que se discute en la página 109), pero cuando se habla acerca de las tareas que anidan en las tareas que sólo no parece tener mucho sentido.

Me gustaría acercarme a su solución de una manera diferente y, como se mencionó anteriormente, un proyecto debe tener muchas tareas, pero para una tarea tener muchas tareas no parece correcto y quizás deba volver a nombrarse como subtareas O algo por el estilo.

2

Actualmente estoy en un proyecto que hace algo similar. La respuesta que utilicé fue muy elegante: agregué una columna parent_id que apuntaba a otra tarea. Al hacer su modelo, asegúrese de hacer lo siguiente:

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

... y entonces usted puede hacer recursividad por:

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

De esta manera, se puede hacer referencia a sus tareas por su padre o por sus hijos. Al realizar sus rutas, tendrá acceso a una única tarea siempre por

/project/:project_id/task/:task_id 

aunque pueda tener un padre o hijos.

Simplemente asegúrese de que no tenga una tarea que tenga su padre como su hijo o de lo contrario irá en un bucle infinito cuando realice su recursión para encontrar todos los elementos secundarios.Puede agregar la condición a sus scripts de validación para asegurarse de que no.

Consulte también: acts_as_tree

+0

usando 'acts_as_tree' funcionaría también, y dar beneficios adicionales. –