2010-12-13 24 views
7

Je souhaite créer un modèle pour stocker les commentaires relatifs aux articles. J'ai un fort sentiment que dans l'avenir, je veux aussi des commentaires sur d'autres objets dans l'application. Comment puis-je créer des commentaires dans mon application afin qu'elle soit compatible avec l'ajout de nouveaux objets parents. Je veux éviter un scénario où plusieurs contrôleurs/modèles pour chaque objet à commenter la relation. Après avoir regardé la projection de Ryan Bates sur Nested Resource, j'ai une idée précise de la façon dont tp imbrique une ressource sous un seul parent. Comment est-ce que j'obtiens ceci sous 2 ou plus de ressources parentales?Ressource imbriquée avec plusieurs ressources parent dans Rails 3

Merci!

+0

+100 si vous avez vraiment une «prise ferme» sur les ressources imbriquées :) – Zabba

Répondre

5

Pour "avant compatible avec l'ajout de nouveaux objets parent" partie de la question:

Vous pouvez utiliser . Voici un nice example. Voir également RailsCast #154.

Un exemple de la façon dont il pourrait ressembler pour vous:

Les pourrait être comme des colonnes de table comments ceci:

id:integer 
commentable_type:string 
commentable_id:integer 
comment_text:string 

Quelques enregistrements Exemples:

1,'Article',12,'My first comment' #comment on an Article model 
2,'Question',12,'My first comment' #comment on a Question model 
3,'Question',15,'My first comment' #comment on a Question model 
0

Pour répondre à la part sur les routes et trouver la ressource.

Le contrôleur de rails habituel trouverait la ressource enfant du parent.

GET /articles/{parent_id}/comments/{id} 

GET /articles/0/comments/1 

article = articles.find(parent_id = 0) 
comment = article.comments.find(id = 1) 

Vous ne pouvez pas faire cela avec des parents polymorphes. Vous devriez trouver le parent de l'enfant.

GET /article/{parent_id}/comments/{id} 
GET /questions/{parent_id}/comments/{id} 

GET /article/0/comments/1 
GET /questions/0/comments/1 

parent = comments.select(parent_id = 0).parent 
comment = parent.comments.find(id = 1) 

Il est possible que vos routes transmettent un type au contrôleur.

GET /{parent_type}/{parent_id}/comments/{id} 

GET /article/0/comments/1 
GET /questions/0/comments/1 

parent = parent_type.find(parent_id = 0) 
comment = parent.comments.find(id = 1) 

(je ne l'ai pas essayé cette approche, ce qui est évidemment pseudocode.)

... Modifier

Je suppose que vous pouvez aussi simplement ajouter un paramètres pour chaque type de parent.

GET /article/{article_id}/comments/{id} 
GET /questions/{question_id}/comments/{id} 

GET /article/0/comments/1 
GET /questions/0/comments/1 

if article_id 
    article = articles.find(article_id = 0) 
    comment = article.comments.find(id = 1) 

if question_id 
    question = questions.find(question_id = 0) 
    comment = question.comments.find(id = 1)