I am trying to implement comment replying feature to my project, however i am not very sure with the method i m using. My basic idea is to keep all the comments in one table, while having another table comments_replies which will have the parent comment(comment) and the comment(reply). now i have something like this is migrations of 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
and in model comments_reply.rb
belongs_to :comment, class_name: 'Comment'
and in model comment.rb
has_many :comments_replies, foreign_key: :parent_comment_id, foreign_key: :reply_comment_id
as for the second part since i m trying to use RSPEC for testing purposes, in model comments_reply_spec.rb i have:
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
but i am not sure how to test this case properly, so any suggestions would be appreciated
What you are trying to achieve could be done from "Comment" model itself. You just need another column 'parent_id' in "Comment" which will reference to parent Comment in same table. For all those main "Comments"(which are not replied to any comment) column 'parent_id' will be null.
So your model will look like below
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
With your current approach
You have specify association with two foreign_key which is wrong. In your "Comment" model you need to association. 1) for all replies of a comment 2) For getting parent comment.
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
Also in your CommentReply model
belongs_to :parent_comment, foreign_key: :parent_comment_id, class_name: 'Comment'
belongs_to :reply_comment, foreign_key: :reply_comment_id, class_name: 'Comment'
Your specs looks like below
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