从同一个表中的一个表中获取2个外键

时间:2017-02-15 05:14:22

标签: ruby-on-rails rspec rails-migrations

我正在尝试为我的项目实现评论回复功能,但是我不太确定使用的方法。我的基本想法是将所有注释保留在一个表中,同时使用另一个表 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

但我不确定如何正确测试这个案例,所以任何建议都会受到赞赏

1 个答案:

答案 0 :(得分:1)

你想要实现的目标可以从"评论"模特本身。您只需要另一列' parent_id' in"评论"它将在同一个表中引用父注释。对于所有主要"评论"(未回复任何评论)列' parent_id'将为null。

所以你的模型将如下所示

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的关联,这是错误的。在你的评论"您需要关联的模型。 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