##開発環境
Ruby 2.6.5
Rails 6.1.3
##テーブルの作成
投稿内容であるcontentと、誰が投稿したのかというuser_idが入るようにします。
create_comments.rb
$ rails g model post content:string user:references
$ rails db:migrate
##モデルとマイグレーションの確認と関連付け
models/post.rb
class Post < ApplicationRecord
has_many :comments, dependent: :destroy
end
models/user.rb
class User < ApplicationRecord
has_many :comments, dependent: :destroy
end
commentモデルに関してはコメントの内容のcontentは空文字ではないようにし、文字数を最大100字にしました。user_id,post_idは存在するかどうかについて検証しています。
models/comment.rb
class Comment < ApplicationRecord
validates :content, { presence: true, length: { maximum: 100 } }
validates :user_id, { presence: true }
validates :post_id, { presence: true }
end
##コントローラーの作成
current_userとして取得しているPostとCommentには全て、ログインユーザーのidが格納されています。
$ rails g controller comments
###postsコントローラーの作成
controllers/posts_controller.rb
class PostsController < ApplicationController
def show
@post = Post.find_by(id: params[:id])
@comments = @post.comments
@comment = Comment.new
@user = @post.user
@likes_count = Like.where(post_id: @post.id).count
end
###commentsコントローラーの作成
controllers/comments_controller.rb
protect_from_forgery except: [:create]
def create
@post = Post.find_by(params[:post_id])
@comments = Comment.new(
content: params[:content],
user_id: @current_user.id,
post_id: @post.id
)
if @comments.save
flash[:notice] = 'コメントを作成しました'
redirect_to("/posts/#{params[:post_id]}")
else
flash[:notice] = 'コメントの作成に失敗しました'
redirect_to("/posts/#{params[:post_id]}")
end
end
def destroy
@post = Post.find_by(params[:post_id])
@comments = Comment.find_by(params[:id])
@comments.destroy
flash[:notice] = 'コメントを削除しました'
redirect_to("/posts/#{params[:post_id]}")
end
end
##コメント投稿機能のビューの作成
app/views/posts/show.html
<h2>コメント一覧</h2>
<% @comments.each do |comment| %>
<div class="posts-show-item">
<div class="post-user-name">
<img src="<%= "/user_images/#{@user.image_name}" %>">
<%= link_to(@user.name, "/users/#{@user.id}") %>
</div>
<p>
<%= comment.content %>
</p>
<div class="post-time">
<%= @post.created_at %>
</div>
<% if comment.user_id == @current_user.id %>
<div class="post-menus">
<%= link_to("削除", "/comments/#{@post.id}/destroy", {method: "post"}) %>
</div>
<% end %>
<% end %>
</div>
<%= form_tag("/comments/:post_id/create") do %>
<div class="form">
<div class="form-body">
<textarea name="content"><%= @comment.content %></textarea>
<input type="submit" value="コメントする">
<% end %>
</div>
</div>
##ルーティングの作成
app/config/routes.rb
resources :users, only: %i[index show]
resources :posts, only: %i[index show create] do
resources :comments, only: [:create]
end
post 'comments/:id/create' => 'comments#create'
get 'comments/:id/destroy' => 'comments#destroy'
##参考にした記事
【Ruby on Rails】コメント機能実装
【Rails】コメント機能の実装手順メモ