結構個人的には苦労したため備忘録です。
利用環境
・ruby 2.7.3
・Rails 6.1.4
実装内容
ユーザの投稿(post)に対してコメント機能(comment)の実装
CommentテーブルはPostとUserの中間テーブルとします。
PostとUserはすでに作成済み前提で記載します。
コメント機能と関係のないコードは省略しております。
モデル作成
Commentモデルの作成
ターミナル
$ rails g model Comment content:text user_id:integer post_id:integer
$ rails db:migrate
アソシエーション(関連付け)
それぞれのモデルに下記を追記する。
dependent: :destroy
は user
が削除された際に post
と comment
も同時に削除させるため
app/models/user.rb
class User < ApplicationRecord
has_many :posts, dependent: :destroy
has_many :comments, dependent: :destroy
end
app/models/post.rb
class Post < ApplicationRecord
belongs_to :user
has_many :comments, dependent: :destroy
end
app/models/comment.rb
class Comment < ApplicationRecord
belongs_to :user
belongs_to :post
validates :content, presence: true
end
コントローラーの作成と編集
comments
コントローラーを作成
ターミナル
$ rails g controller comments
posts
と comments
コントローラーの編集
app/controllers/posts_controller.rb
class PostsController < ApplicationController
def show
@post = Post.find(params[:id])
@comment = Comment.new
@comments = @post.comments.order(created_at: :desc)
end
end
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
# 投稿に紐づいたコメントを作成
@comment = @post.comments.build(comment_params)
@comment.user_id = current_user.id
@comment.save
redirect_to @post
end
def destroy
@comment = Comment.find(params[:id])
@comment.destroy
redirect_to @post
end
private
def comment_params
params.require(:comment).permit(:content, :post_id, :user_id)
end
end
ルートの設定
config/routes.rb
Rails.application.routes.draw do
resources :users
resources :posts, only: [:index, :show, :new, :create] do
resources :comments, only: [:create, :destroy]
end
end
Viewファイル
app/views/posts/show.html
<div class="row">
<% if user_signed_in? %>
<div class="comment-create">
<h3 class="text-left">コメントを投稿する</h3>
<%= render partial: 'comments/form', locals: { comment: @comment, post: @post } %>
</div>
<% end %>
<hr>
<h2 class="text-comments">コメント一覧</h2>
<div class="comments_area">
<%= render partial: 'comments/index', locals: { comments: @comments } %>
</div>
</div>
app/views/comments/_index.html
<!---- コメント内容 ----->
<a class="comment-count">コメント数<%= comments.count %>件</a>
<% comments.each do |comment| %>
<% unless comment.id.nil? %>
<div class="comment-box">
<p> <%= comment.user.username %> <%= comment.created_at.strftime('%Y/%m/%d %H:%M:%S') %></p>
<%= simple_format(h comment.content) %>
<% if comment.user == current_user %>
<%= link_to post_comment_path(comment.post_id, comment.id), method: :delete, remote: true, class: "comment_destroy" do %>
<i class="fas fa-trash" style="color: black;"></i>
<% end %>
<% end %>
</div>
<% end %>
<% end %>
app/views/comments/_form.html
<!---- コメント入力フォーム ----->
<%= form_with(model: [post, comment], url: post_comments_path(@post) ) do |f| %>
<%= f.text_area :content, size: "10x5", class:"area-field" %>
<%= f.submit "書き込む", class:"submit-btn" %>
<% end %>
こんな感じでコメント機能は終わりです。