在同一个 table rails 中有一个 table 的 2 个外键

Having 2 foreign keys from one table in the same table rails

我正在尝试为我的项目实现评论回复功能,但是我不太确定我使用的方法。我的基本想法是将所有评论保留在一个 table 中,同时将另一个 table comments_replies 包含父评论(评论)和评论(回复)。现在我有这样的东西是 comments_replies:

的迁移
create_table :comments_replies do |t|
  t.integer :parent_comment_id, index: true, foreign_key_column_for: :comments, null: false
  t.integer :reply_comment_id, index: true, foreign_key_column_for: :comments, null: false
  t.timestamps null: false
end

在模型中 comments_reply.rb

belongs_to :comment, class_name: 'Comment'

在模型中 comment.rb

has_many :comments_replies, foreign_key: :parent_comment_id, foreign_key: :reply_comment_id

至于第二部分,因为我试图使用 RSPEC 进行测试,在模型 comments_reply_spec.rb 中我有:

require 'rails_helper'

RSpec.describe CommentsReply, type: :model do
  let(:comments_reply) { create(:comments_reply) }
  subject { comments_reply }

  it { is_expected.to respond_to(:parent_comment_id) }
  it { is_expected.to respond_to(:reply_comment_id) }
end

但我不确定如何正确测试这个案例,所以任何建议都将不胜感激

您想要实现的目标可以通过 "Comment" 模型本身来完成。您只需要 "Comment" 中的另一列 'parent_id',它将引用同一 table 中的父 Comment。对于所有那些主要 "Comments"(未回复任何评论)列 'parent_id' 将为空。

因此您的模型将如下所示

class Comment 
  belongs_to :parent_comment, foreign_key: :parent_comment_id, class_name: 'Comment'
  has_many :replies, foreign_key: :parent_comment_id, class_name: 'Comment'
end

用你目前的方法

您指定了与两个 foreign_key 的关联,这是错误的。在您的 "Comment" 模型中,您需要关联。 1) 评论的所有回复 2) 获取家长评论。

has_many :comments_replies, foreign_key: :parent_comment_id
has_many :replies, through: :comment_replies

has_one :parent_comment_reply, foreign_key: :reply_comment_id, class_name: 'CommentReply'
has_one :parent_comment, through: :parent_comment_reply

也在您的 CommentReply 模型中

belongs_to :parent_comment, foreign_key: :parent_comment_id, class_name: 'Comment'
belongs_to :reply_comment, foreign_key: :reply_comment_id, class_name: 'Comment'

您的规格如下所示

require 'rails_helper'

RSpec.describe CommentsReply, type: :model do
  let(:parent_comment){ create(:comment) }
  let(:child_comment) { create(:comment) }

  let(:comment_reply) { create(:comment_reply, parent_comment_id: parent_comment.id, reply_comment_id: child_comment.id) }

  subject { comment_reply }

  it { is_expected.to respond_to(:parent_comment_id) }
  it { is_expected.to respond_to(:reply_comment_id) }

  it "should correctly identify the parent/child relationship" do
    expect(comment_reply.reply_comment.id).to be_eql(child_comment.id)
    expect(comment_reply.parent_comment.id).to be_eql(parent_comment.id)
  end

end