2008-10-06 9 views
6

J'ai une application Rails pour la gestion de projet où il y a des modèles de projet et de tâche. Un projet peut avoir plusieurs tâches, mais une tâche peut aussi avoir plusieurs tâches, à l'infini.Rails récursifs Ressources imbriquées

L'utilisation des ressources imbriquées, nous pouvons avoir des projets// 1/tâches,/projets/1/tâches/nouvelles/projets/1/tâches/3/modifier etc.

Cependant, comment vous représentez la nature récursive des tâches RESTfully? Je ne veux pas aller un autre niveau profond, donc peut-être la suivante ferait:

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

Cela me donnerait les urls suivantes:

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

Ou peut-être en ce qui concerne une tâche individuelle que je peux il suffit d'utiliser/tasks/45/edit

Est-ce une conception raisonnable?

Cam

Répondre

3

Il n'y a aucune raison pour qu'ils aient des adresses URL décentes.

logiquement:

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

il n'y a aucune raison à mon humble avis d'exiger que les URL soient associatives, vous n'allez pas besoin de savoir que la tâche 5 est un enfant de la tâche 3 à modifier la tâche 5.

6

Aller au-delà d'une seule route imbriquée est généralement considéré comme une mauvaise idée.

De la page 108 de The Way Rails:

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

Aujourd'hui, certains soutiendraient cette (dont il est question à la page 109) mais quand vous parlez des tâches de nidification avec des tâches juste ne semble pas avoir beaucoup de sens.

Je voudrais aborder votre solution d'une manière différente et comme il a été mentionné ci-dessus, un projet devrait avoir de nombreuses tâches, mais pour une tâche d'avoir beaucoup de tâches ne semble pas correctes et peut-être devraient être renommées sous-tâches Ou quelque chose de ce genre.

2

Je suis actuellement sur un projet qui fait quelque chose de similaire. La réponse que j'ai utilisée était très élégante quand j'ai ajouté une colonne parent_id qui pointait vers une autre tâche. Quand vous faites votre modèle, assurez-vous de faire ce qui suit:

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

... et vous pouvez le faire par récursion:

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

De cette façon, vous pouvez référencer vos tâches par son parent ou par ses enfants. Lorsque vous effectuez vos itinéraires, vous devez toujours accéder à une seule tâche par

/project/:project_id/task/:task_id 

même s'il peut avoir un parent ou des enfants. Assurez-vous simplement que vous n'avez pas de tâche dont le parent est le même que son enfant, sinon vous entrerez dans une boucle infinie lorsque vous effectuerez votre récursion pour trouver tous les enfants.Vous pouvez ajouter la condition à vos scripts de validation pour vous assurer que ce n'est pas le cas.

Voir aussi: acts_as_tree

+0

en utilisant 'acts_as_tree' fonctionnerait aussi, et donner des avantages supplémentaires. –

Questions connexes