LoginSignup
1
0

「コメントに対するコメント」をモデルで表現してみた!

Last updated at Posted at 2024-06-26

動作環境

vscode、ruby3.3.0、rails7.1.3.4

実装したかったこと

x(旧twitter)のようなクローンアプリを作っていたのですが、投稿文に対するコメントに対して更にコメントする機能を実装してみました。
探せば山ほど参考になる記事は出てくると思ったのですが、今回は自分のテーブルや関係性の理解度を確認するために、敢えて自分で試行錯誤しながら一から作ってみました!💪

実装のゴール

コメントの子要素を取得できる。
コメントの3階層まで。4階層目のコメントは作成できない。(コメントのコメントのコメントまでは作成できる)

実装前のモデルの状態

user→post→comment
(既にpostへのコメント機能は作成済みです)

app/models/user.rb
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy
app/models/post.rb
belongs_to :user
has_many :comments, dependent: :destroy
app/models/comment.rb
belongs_to :user
belongs_to :post, counter_cache: true

コメントの子コメントを取得できるようにする

コメントと子コメントを1対多の関係にする

コメントにparent_comment_idカラムを追加します。

db/migrate/20240621054017_add_parent_comments_to_comment.rb
class AddParentCommentsToComment < ActiveRecord::Migration[7.1]
  def change
    add_column :comments, :parent_comment_id, :integer
    add_foreign_key :comments, :comments, column: :parent_comment_id
  end
end

子コメントをchild_commentsという名前で定義します。

app/models/comment.rb
has_many :child_comments, class_name: 'Comment', foreign_key: 'parent_comment_id', inverse_of: :parent_comment, dependent: :destroy

コメントの親コメントを取得できるよう、親コメントをparent_commentという名前で定義します。
1階層目のコメントは親コメントがいないので、parent_commentとの紐付けは任意にします。

app/models/comment.rb
belongs_to :parent_comment, class_name: 'Comment', inverse_of: :child_comments, optional: true

3階層目以降のコメントは作成できないようにする

作成しようとするコメントのコメントのコメントのparent_comment_idカラムに値が入っていれば、つまり既に3階層になっていれば、保存できないようにするという処理を書きます。
どこかイけてない気がしなくもない…
FBをもとに改良したいと思います。

app/models/comment.rb
validate :layer_over_three

def layer_over_three
  if self.parent_comment&.parent_comment&.parent_comment_id.present?
    errors.add(:base, 'parent comment already has layers over three')
  end
end

最後に

初めてコメントに対するコメント機能を作成しました。
社内のチャットシステムを見ながらいつも、どうやって実装しているんだろう?自分も実装してみたいと思っていたので、とりあえず実現できたのは良かったです。
画面の作成がまだ途中なので、画面の作成の完了次第、ビューファイルもアップしようと思います!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0