Railsを使って、●イッターみたく一覧画面でコメントしてみたいなーと
思ったので作りました!!
前提
以下の項目を既に実施している前提として話を進めます!
- 投稿機能の実装
- deviseを用いたユーザー機能の実装
- 簡単なコメント機能の実装
Viewの編集
HTML・Rails側で主に実施することは以下の通りです。
- 投稿毎にコメントを表示する
- コメントの表示・非表示用のボタンを作る
- 各投稿を見分けるために、投稿のIDをつけておく
- コメントのフォームを作る
- 投稿毎にコメントできるように、各フォームでインスタンスを生成
index.html.erb
<div class='container'>
<h1>Posts</h1>
<div class='row'>
<% @posts.each do |post| %>
<div class='col-md-3 card'>
<%= image_tag post.image_url, class: 'card-img-top', size: "250x200" if post.image? %>
<div class='card-body'>
<div class='card-text'>
<%= post.body %>
</div>
</div>
<div class='card-body'>
<%= link_to '詳細', post, class: 'card-link' %>
<% if current_user.id == post.user_id %>
<%= link_to '編集', edit_post_path(post), class: 'card-link' %>
<%= link_to '削除', post, method: :delete, data: { confirm: '本当に削除しますか?' }, class: 'card-link' %>
<% end %>
+ <div style='display: flex; flex-direction: column;'>
+ <button
+ id='show_comment_buttons_<%= post.id %>'
+ onclick='onClickComment(<%= post.id%>)'
+ style='width: 6rem;'>
+ コメント
+ </button>
+ <div id='comment_list_<%= post.id%>' style='display: none;'>
+ <% post.comments.each do |comment| %>
+ <%= comment.user.name %>
+ <%= comment.content %><br>
+ <% end %>
+ </div>
+ <div id='comment_forms_<%= post.id%>' style='display: none;'>
+ <% if user_signed_in? %>
+ <%= form_with(model: [post, Comment.new], local: true) do |f| %>
+ <%= f.text_area :content %>
+ <%= button_tag type: "submit" do %>
+ <i class="far fa-comments"></i> コメントする
+ <% end %>
+ <% end %>
+ <button
+ id='hide_comment_buttons_<%= post.id %>'
+ onclick='onClickHideComment(<%= post.id%>)'
+ style='display: none; width: 3.5rem;'>
+ 閉じる
+ </button>
+ <% end %>
+ </div>
+ </div>
</div>
</div>
<% end %>
</div>
</div>
表示切り替え
切り替えの動作として必要なことは以下の通りです。
- 表示用の関数を作成
- 各要素のDOMを取得
- コメントフォーム
- 各種ボタン
- コメントの表示
- 要素毎にCSSでBlock(表示),None(非表示)を設定
- 各要素のDOMを取得
- 非表示用の関数を作成
- DOMを取得
- 表示用関数の真逆
index.html.erb
<script>
function onClickComment (id) {
const form = document.getElementById(`comment_forms_${id}`)
const showButton = document.getElementById(`show_comment_buttons_${id}`)
const hideButton = document.getElementById(`hide_comment_buttons_${id}`)
const commentList = document.getElementById(`comment_list_${id}`)
form.style.display = "block"
showButton.style.display = "none"
hideButton.style.display = "block"
commentList.style.display = "block"
}
function onClickHideComment(id) {
const form = document.getElementById(`comment_forms_${id}`)
const showButton = document.getElementById(`show_comment_buttons_${id}`)
const hideButton = document.getElementById(`hide_comment_buttons_${id}`)
const commentList = document.getElementById(`comment_list_${id}`)
form.style.display = "none"
showButton.style.display = "block"
hideButton.style.display = "none"
commentList.style.display = "none"
}
</script>
感想
●イッターのような形式での表示自体は、こんな感じでいけます!
完全に同じ動作にするには、非同期でコメント機能を実装したり
CSSの工夫をしたり、と必要になります。
もっと青い鳥に近づけたい!という人は頑張ってみてください🔥