コメント機能

内容

投稿詳細ページでコメント機能を実装する

コメント機能

1. モデルを作成

Commentモデルを作成し、マイグレーションファイルを編集する
ターミナル

% rails g model comment

db/migrate/20XXXXXXXXXXXX_create_comments.rb

t.text :comment
t.references :user, null: false, foreign_key: true
t.references :post, null: false, foreign_key: true

ターミナル

% rails db:migrate

続いてアソシエーションを記述
app/models/comment.rb

belongs_to :user
belongs_to :post

app/models/user.rb

has_many :comments, dependent: :destroy

app/models/post.rb

has_many :comments, dependent: :destroy

2. ルーティングを設定

コメントは投稿に紐付くのでルーティングにネストを利用する
routes.rb

resources :posts, except: :index do
  resources :comments, only: %i[create destroy]
end

※いいね機能の時はネストをresource :likeで記述してよかった
→なぜなら1件の投稿に対していいねは1回しかできないため、idを指定しなくても投稿に関連したいいねを削除できるから
※一方、コメント機能ではresources :commentsとしなければならない
→なぜなら1件の投稿に対してコメントは何回でもでき、それを削除したい場合どのコメントを消すかidを指定しなければならないから

3. コントローラーを作成

commentsコントローラーを作成し、createアクションとdestroyアクションを定義
ターミナル

% rails g controller comments

app/controllers/comments_controller.rb

before_action :post_find, only: %i[create destroy]

def create
  @comment = @post.comments.new(comment_params)
  if @comment.save
    redirect_to post_path(@post.id)
  else
    @comments = @post.comments.includes(:user)
    render post_path(@post.id)
  end
end

def destroy
  @comment = @post.comments.find(params[:id])
  @comment.destroy
  redirect_to post_path(@post.id)
end

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

def comment_params
  params.require(:comment).permit(:comment).merge(user_id: current_user.id)
end

4. ビューを編集

投稿詳細ページにコメント投稿フォーム、およびコメント表示欄を作成
app/views/posts/show.html.erb

<%= form_with(model: [@post, @comment], local: true) do |f| %>
  <%= f.text_area :comment, placeholder: "コメントする", maxlength: "140" %>
  <%= f.submit "送信" %>
<% end %>

<% @comments.each do |comment| %>
  <p>
    <strong><%= link_to comment.user.nickname, user_path(comment.user.id) %>:</strong>
    <%= comment.comment %>
    <strong>[<%= link_to "削除", post_comment_path(post_id: @post.id, id: comment.id), method: :delete, data: {confirm: "コメントを削除してもよろしいですか?"} %>]</strong>
  </p>
<% end %>

5. Postコントローラーを編集

app/controllers/posts_controller.rb

def show
  @comment = Comment.new
  @comments = @post.comments.includes(:user)
end

6. ビューの微修正

コメント欄に投稿時刻等を記述
時刻の設定には、Railsのapplication.rbという設定ファイルを扱う config/application.rb

class Application < Rails::Application
  # Initialize configuration defaults for originally generated Rails version.
  config.load_defaults 6.0 
  config.i18n.default_locale = :ja
  config.time_zone = 'Tokyo'

ja.ymlファイルを作成して、表示する時刻のフォーマットを設定
config/locales/ja.yml

ja:
  time:
    formats:
      default: "%Y/%m/%d %H:%M:%S"

この時刻設定を元に、lメソッドを利用して、表示する時刻へ反映
show.html.erb

<%= l comment.created_at %>

所感

もっとコードを簡潔にかけるかもしれないが、今の私にとってはこれが精一杯

次回

コメント機能の非同期化、もしくは住所登録/検索機能を実装する