Nested resource with multiple parent resources in Rails 3
I want to create a model to store comments related to articles. I have a strong feeling that in the future开发者_如何学运维 I will want comments on other objects in the app too. How do I design commenting in my app so that it will be forward compatible with adding new parent objects. I want to avoid a scenario where have multiple controllers/models for each object to comment relationship.
After watching Ryan Bates screen cast on Nested Resource I have a firm grasp on how tp nest a resource under a single parent. How do I achieve this under 2 or more parent resources?
Thanks!
For "forward compatible with adding new parent objects" part of the question:
You could use Polymorphic Associations. Here's a nice example. Also see RailsCast #154.
An example of how it could look like for you:
The comments
table columns' could be like this:
id:integer
commentable_type:string
commentable_id:integer
comment_text:string
Some Sample records:
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
To answer the part about the routes and finding the resource.
The usual rails controller would find the child resource from the parent.
GET /articles/{parent_id}/comments/{id}
GET /articles/0/comments/1
article = articles.find(parent_id = 0)
comment = article.comments.find(id = 1)
You can't do that with polymorphic parents. You would have to find the parent from the child.
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)
It might possible to make your routes pass a type to the controller.
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)
(I've not tried this approach, this is obviously pseudocode.)
Edit ...
I suppose you could also just add one parameters for each type of 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)
精彩评论