【问题标题】:Do all join tables have tables?所有连接表都有表吗?
【发布时间】:2026-02-11 15:45:01
【问题描述】:

比如我有一个cmets模型,我有一个post模型,但是cmets可以评论其他cmets。

看来我需要一个连接表,我将调用commentables。要创建这个,我真的需要创建一个带有 post_id 和 comment_id 的可评论表吗?

或者我可以不做这样的事情吗:

has_many            :comments,
                    :through => :commentables,
                    :source => :post

不太确定实现此目的的最佳方法是什么。我是个大新手。

【问题讨论】:

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


    【解决方案1】:

    不,在这种情况下您不需要连接表。联接表用于has_and_belongs_to_many 关系,在这种情况下,您不需要其中之一(cmets 不能属于许多帖子,对吗?)。

    您有两种选择。首先是创建多态关系:

    class Post < ActiveRecord::Base
      has_many :comments, :as => :parent
    end
    
    class Comment < ActiveRecord::Base
      belongs_to :parent, :polymorphic => true
      has_many   :children, :class_name => 'Comment', :as => :parent # We need to point this relationship to the Comment model, otherwise Rails will look for a 'Child' model
    end
    

    这将允许评论属于帖子或其他评论。 Comment.last.parent 将返回 PostComment 记录。

    第二种选择是让所有的cmet都属于一个特定的帖子,但是有自己的父子关系:

    class Post < ActiveRecord::Base
      has_many :comments
    end
    
    class Comment < ActiveRecord::Base
      belongs_to :post
      belongs_to :parent, :class_name => 'Comment'   # We need to point this relationship to the Comment model, otherwise Rails will look for a 'Parent' model
      has_many   :children, :class_name => 'Comment' # We need to point this relationship to the Comment model, otherwise Rails will look for a 'Child' model
    end
    

    这样,您的 cmets 将始终属于某个帖子,并且有可能属于另一个评论。

    如果您打算嵌套 cmets(至少不止一层),我建议您使用第二个选项。这将允许您在一个查询中获取特定帖子的所有 cmets(而不必为每个评论查找子项),并且您可以在呈现之前对应用程序中的 cmets 进行排序。但无论哪种方式都应该有效。

    【讨论】:

    • 嘿 Vonconrad,我很好奇您是否也知道如何为此设置表单?我一直在尝试解决这个问题:*.com/questions/3938173/…