【问题标题】:Nested resource with multiple parent resources in Rails 3Rails 3中具有多个父资源的嵌套资源
【发布时间】:2011-09-22 05:29:56
【问题描述】:

我想创建一个模型来存储与文章相关的 cmets。我有一种强烈的感觉,将来我也希望在应用程序中的其他对象上使用 cmets。如何在我的应用程序中设计评论,以便它与添加新的父对象向前兼容。我想避免每个对象都有多个控制器/模型来注释关系的情况。

在观看了 Nested Resource 上的 Ryan Bates 投屏后,我牢牢掌握了如何将资源嵌套在单亲之下。如何在 2 个或更多父资源下实现这一目标?

谢谢!

【问题讨论】:

  • +100 如果你真的对嵌套资源有“牢牢把握”:)

标签: ruby-on-rails ruby-on-rails-3


【解决方案1】:

对于“与添加新父对象的前向兼容”部分问题:

您可以使用Polymorphic Associations。这是nice example。另见RailsCast #154

一个例子,它看起来像你:

comments 表列可能是这样的:

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

一些示例记录:

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

【讨论】:

    【解决方案2】:

    回答关于路线和寻找资源的部分。

    通常的 rails 控制器会从父资源中找到子资源。

    GET /articles/{parent_id}/comments/{id}
    
    GET /articles/0/comments/1
    
    article = articles.find(parent_id = 0)
    comment = article.comments.find(id = 1)
    

    你不能对多态的父母做到这一点。您必须从孩子中找到父母。

    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)
    

    也许可以让你的路由将一个类型传递给控制器​​。

    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)
    

    (这个方法我没试过,这明显是伪代码。)

    编辑 ...

    我想您也可以为每种类型的父级添加一个参数。

    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)
    

    【讨论】: