7
2

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 2021-05-27

目的

Railsで作成したアプリにコメント機能を導入する。

開発環境

macOS: Big Sur
Rubyバージョン: 2.6.5
Railsバージョン: 6.0.0

前提

手順

  1. Commentモデルの作成
  2. アソシエーションの設定
  3. バリデーションの設定
  4. ルーティングの設定
  5. comentsコントローラーの作成・編集
  6. postsコントローラーの編集
  7. ビューファイルの編集

前置き

今回はRailsで作成したアプリにコメント機能を導入します。
具体的には、ユーザーが投稿した投稿詳細ページにコメントを追加、削除できる機能です。

Commentモデルの作成

それでは早速始めていきます!
まずCommentモデルを作成します。

ターミナル
% rails g model comment

コメント内容は、textカラムとしています。

db/migrate/20XXXXXXXXXXXX_create_comments.rb
class CreateComments < ActiveRecord::Migration[6.0]
  def change
    create_table :comments do |t|
      t.text       :text, null: false
      t.references :user, null: false, foreign_key: true
      t.references :post, null: false, foreign_key: true
      t.timestamps
    end
  end
end

マイグレーションを編集し、マイグレートしましょう!

ターミナル
% rails db:migrate

以上でモデルは完成です。

アソシエーションの設定

次にアソシエーションを設定していきます。

app/models/comment.rb
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :post
end
app/models/user.rb
class User < ApplicationRecord
#省略
  has_many :comments, dependent: :destroy
end
app/models/post.rb
class Post < ApplicationRecord
#省略
  has_many :comments, dependent: :destroy
end

以上でアソシエーションの設定ができました!

バリデーションの設定

続いてバリデーションの設定です!

app/models/comment.rb
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :post

  validates :text, presence: true
end

コメントが空では保存できないようにします。

ルーティングの設定

次はルーティングを設定します!
コメントには必ず投稿が紐づいているため、ルーティングをネストさせます。

config/routes.rb
Rails.application.routes.draw do
#省略
  resources :posts do
    resources :comments, only: [:create, :destroy]
  end
#省略
end

コメントは作成機能削除機能を実装します!

comentsコントローラーの作成・編集

コントローラーを作成していきます。

ターミナル
% rails g controller comments

続いてアクションの定義も行います!
ここで、保存が出来ない場合の処理についても実装していきます。
今回は、renderを用いて詳細ページのビューファイルを表示するようにします。

app/controllers/comments_controller.rb
class CommentsController < ApplicationController
  before_action :authenticate_user!

  def create
    @comment = Comment.new(comment_params)
    if @comment.save
      redirect_to post_path(@comment.post)
    else
      @post = @comment.post
      @comments = @post.comments.includes(:user)
      render "posts/show"
    end
  end

  def destroy
    comment = Comment.find_by(id: params[:id], post_id: params[:post_id])
    comment.destroy
    redirect_to post_path(comment.post)
  end

  private
  def comment_params
    params.require(:comment).permit(:text).merge(user_id: current_user.id, post_id: params[:post_id])
  end
end

destroyアクション内ですが、ルーティングでネストさせているため、引数は2つ指定します。
これでコメント作成の機能はできたので、
次にコメントを表示するための実装をしていきます!

postsコントローラーの編集

まずpostsコントローラーの編集です。
コメントは投稿詳細ページに表示していくため、showアクション内に追記していきます。

app/controllers/posts_controller.rb
class PostsController < ApplicationController
#省略
  def show
    @post = Post.find(params[:id])
    @comment = Comment.new
    @comments = @post.comments.includes(:user)
  end
#省略
end

includesでN+1問題も解決しています。

ビューファイルの編集

最後にビューファイルの編集です!
コメント送信フォームコメント一覧の表示を実装していきます。

app/views/posts/show.html.erb
<% if user_signed_in? %>
  <%= form_with model: [@post, @comment], local: true do |form| %>
    <%= form.text_area :text, placeholder: "コメントする", rows: "2" %>
    <%= form.submit "送信" %>
  <% end %>
<% else %>
  <strong><p>コメントの投稿には新規登録/ログインが必要です</p></strong>
<% end %>

<h4><コメント一覧></h4>
<% @comments.each do |comment| %>
  <p>
    <strong><%= comment.user.name %>:</strong>
    <%= comment.text %>
    <% if user_signed_in? && current_user.id == comment.user_id %>
      <%= link_to "削除", post_comment_path(comment.post.id, comment.id), method: :delete %>
    <% end %>
  </p>
<% end %>

条件分岐で、ログインしていない場合はコメントを投稿できないようにしています。

コメント一覧表示では、コメントコメントしたユーザー名を表示しています。
また、コメント投稿者のみ削除リンクが表示されるようにしています。

最後に

以上でコメント機能の追加ができました。
CSSを実装していないため、簡素な見た目となっています。
必要に応じて各自、編集をお願いします。
では。

7
2
1

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
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?