2
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】コメント機能(登録・表示・削除)

Last updated at Posted at 2020-09-02

投稿に対するコメント機能実装の備忘録。

ゴール

  • Userテーブル、Postテーブルに紐付く、Comentテーブル(中間テーブル)でコメントを管理。
  • Comentテーブルは、コメント内容、コメントしたpost_id、コメント投稿者user_idカラムを設置。
  • (前提) ユーザー機能は、devise を使用。

実装

コメントモデルとテーブル作成

  • コメントモデルとテーブル(コメント内容、コメント投稿者)を作成
ターミナル
% rails g model Comment comment_text:text user:references post:references
% rails g controller Comments
% rails db:migrate

モデルにアソシエーション追加。

Commentモデル
belongs_to :post      # Comment.post で、コメントされた投稿取得
belongs_to :user      # Comment.user で、コメント投稿者取得
Userモデル
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy    # User.comments で、ユーザーのコメント取得

validates :comment_text, presence: true, length: { maximum: 1000 }   # 空をバリデーション、文字数制限とか。。
Postモデル
belongs_to :user
has_many :comments, dependent: :destroy    # Post.comments で、その投稿のコメント取得

詳細ページにコメント欄設置

詳細ページ
-# コメント表示
= @comments.each do |c|
  = c.user.name
  - if c.user.id == @post.user.id   # 記事投稿者
    %p 投稿者
  = simple_format(c.comment_text)   # 改行ありで表示
  = link_to '削除', post_comment_path(@post, c), data: {confirm: '本当に削除しますか?'}, method: :delete
    -# コメント削除には、@post(親), @commentsのc に渡す必要がある

-# コメント投稿
= form_for [@post, @comment], local: true do |f|   # comment は、postに紐づくので、配列で書く
  = f.text_area :comment_test
  = f.submit "投稿"

一覧表示ページに紐づくよう、ルーティングを設定。

routes.rb
resources :posts do   # posts に紐づかせるため、ネストにする 
  resources :comments, only: [:create, :destroy] 
end

コントローラーにアクション定義

コメント登録/削除アクション(create/destroy)。

ターミナル
% rails g controller comments
commentsコントローラー
before_action :set_post
before_action :authenticate_user!    # ログイン中のみ許可

def create
  @comment = @post.comments.create(comment_params)
  if @comment.save
    redirect_to blog_path(@post) notice: 'コメントしました'
  else
    flash.now[:alert] = 'コメントに失敗しました'
    render post_path(@post)
  end
end

def destroy
  @comment = Comment.find(params[:id])
  if @comment.destroy
    redirect_to post_path(@post), notice: 'コメントを削除しました'
  else
    flash.now[:alert] = 'コメント削除に失敗しました'
    render post_path(@post)
  end
end

private
def set_post
  @post = Post.find(params[:post_id])
end

def comment_params
  params.required(:comment).permit(:comment_text).merge(user_id: current_user.id, post_id: params[:post_id])
end

投稿ページ(show)に、コメント一覧も表示するので、posts#showで、コメントデータ取得。

postsコントローラー
      :
def show
  @post = Post.find(params[:id])

  @comment = Comment.new     # フォーム用のインスタンス作成(コメント追加用)
  @comments = @post.comments # コメント一覧表示用
end
      :
2
14
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
2
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?