【Rails】 코멘트 기능의 구현
소개
블로그 같은 웹 서비스에 코멘트 기능을 추가해 보았습니다.
자신의 메모용, 그리고 같은 기능을 구현하려고 하는 초학자 분의 참고가 되면 다행입니다!
전제
Ruby : 2.6.4
Rails : 5.2.3
사용자 인증에 devise를 사용하고 있습니다.
Comment Model 작성
User 모델의 사용자가 Post 모델에 주석을 달 수 있도록 합니다.
구현 방법으로서는, 팔로우 기능과 같이 중간 테이블을 준비해, 그 중간 테이블(Comment Model)의 content 컬럼에
실제 주석을 추가합니다.
$ rails g model comment content:string user:references post:references
$ rails db:migrate
user.rb has_many :comments
post.rb has_many :comments
comment.rbclass Comment < ApplicationRecord
belongs_to :user
belongs_to :post
end
comment.rb에 관한 것이지만, 수동으로 실수로 post_id와의 연관이 잘 작동하지 않는 상태에서
코멘트의 테스트를 행해 버려, 외래 키가 nil이 되어 버려 에러가 되어 버렸습니다.
이 문제의 해결은
comment.rbclass Comment < ApplicationRecord
belongs_to :user
belongs_to :post, optional: true
end
이 방법으로 optional: true를 추가하여 (일시적으로) 해결할 수 있습니다.
여기서 자동 테스트의 고마움을 깨달았습니다 (웃음)
외래 키의 nil을 허가하는 패턴은 별로 없다고 생각하기 때문에, 사용하는 것은 거기까지 없을까라고 생각합니다.
컨트롤러 작성
comments_controller.rb 만들기
$ rails g controller comments
comments_controller.rbclass CommentsController < ApplicationController
before_action :authenticate_user!
def create
post = Post.find(params[:post_id])
@comment = post.comments.build(comment_params)
@comment.user_id = current_user.id
if @comment.save
flash[:success] = "コメントしました"
redirect_back(fallback_location: root_path)
else
flash[:success] = "コメントできませんでした"
redirect_back(fallback_location: root_path)
end
end
private
def comment_params
params.require(:comment).permit(:content)
end
end
create 액션에 대해.
@comment.user_id = current_user.id를 작성하는 이유로,
위의 2행만으로는 코멘트를 한 사용자의 연관을 할 수 없기 때문에 쓰고 있습니다.
라우팅
routes.rb resources :posts do
resources :comments, only: [:create]
end
보기
자신의 경우는 Post의 show.html.erb에 코멘트 일람과 폼을 추가하고 싶었기 때문에 여기에 추가합니다.
app/views/posts.show.html.erb<div class="comment-wrapper border-top mb-10">
<p class="mt-5">コメント一覧</p>
<% @comments.each do |c| %>
<div>
<% unless c.user.blank? %>
<a href="<%= user_path(c.user_id) %>"><%= image_tag c.user.image.to_s,
class:"rounded-circle icon_image mr-3 mb-3"%></a>
<% end %>
<%= c.user.username unless c.user.blank? %>
<br />
<%= c.content %>
</div>
<br />
<% end %>
<% if user_signed_in? %>
<%= form_with(model: [@post, @comment], local: true) do |f| %>
<%= f.text_area :content, class: "form-control", rows: 5 %>
<%= button_tag type: "submit", class: "btn btn-success float-right mt-1" do %>
<i class="far fa-comments"></i> コメントする
<% end %>
<% end %>
<% end %>
</div>
특히 어렵지는 않지만 form_with(model: [ @post , @comment ], local: true) do |f|
comment가 post에 붙어 있기 때문에 배열로 합니다.
posts_controller.rb def show
@post = Post.find(params[:id])
@comments = @post.comments
@comment = @post.comments.build
end
show.html.erb 내에서 사용하는 @comment 및 @comments은 위와 같습니다.
완성
로그인하지 않았을 때
로그인 시
끝에
코멘트 삭제 기능을 붙여 잊고 있었으므로 구현합니다.
뭔가 잘못된 점 등 있으면 댓글이나 트위터로 부탁드립니다!
Reference
이 문제에 관하여(【Rails】 코멘트 기능의 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/__kotaro_/items/8a6bda99dab61d2a72a5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
$ rails g model comment content:string user:references post:references
$ rails db:migrate
has_many :comments
has_many :comments
class Comment < ApplicationRecord
belongs_to :user
belongs_to :post
end
class Comment < ApplicationRecord
belongs_to :user
belongs_to :post, optional: true
end
$ rails g controller comments
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
post = Post.find(params[:post_id])
@comment = post.comments.build(comment_params)
@comment.user_id = current_user.id
if @comment.save
flash[:success] = "コメントしました"
redirect_back(fallback_location: root_path)
else
flash[:success] = "コメントできませんでした"
redirect_back(fallback_location: root_path)
end
end
private
def comment_params
params.require(:comment).permit(:content)
end
end
resources :posts do
resources :comments, only: [:create]
end
<div class="comment-wrapper border-top mb-10">
<p class="mt-5">コメント一覧</p>
<% @comments.each do |c| %>
<div>
<% unless c.user.blank? %>
<a href="<%= user_path(c.user_id) %>"><%= image_tag c.user.image.to_s,
class:"rounded-circle icon_image mr-3 mb-3"%></a>
<% end %>
<%= c.user.username unless c.user.blank? %>
<br />
<%= c.content %>
</div>
<br />
<% end %>
<% if user_signed_in? %>
<%= form_with(model: [@post, @comment], local: true) do |f| %>
<%= f.text_area :content, class: "form-control", rows: 5 %>
<%= button_tag type: "submit", class: "btn btn-success float-right mt-1" do %>
<i class="far fa-comments"></i> コメントする
<% end %>
<% end %>
<% end %>
</div>
def show
@post = Post.find(params[:id])
@comments = @post.comments
@comment = @post.comments.build
end
Reference
이 문제에 관하여(【Rails】 코멘트 기능의 구현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/__kotaro_/items/8a6bda99dab61d2a72a5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)