はじめに
非同期化の失敗を先ほどアウトプットしていましたが、
DM機能の非同期化もまとめておきたいと思います!
完成物
コメントは吹き出しをつけて、送信フォームは下に固定しています!
ER図
今回は非同期化のまとめなので実装方法は割愛しますが、
こちらのER図にて実装しています
実装方法はこちらの記事が大変わかりやすかったです
⚠️全く同じというわけではないと思います!
Viewの記述
テンプレートの作成
非同期化に対応したい箇所をテンプレートにします
今回の場合は、チャット一覧とチャット送信フォームです
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-10 col-lg-8 my-3 p-4 mx-auto">
<div class="text-center">
<%= image_tag @user.get_profile_image(90, 90), class: "rounded-circle mx-auto d-block" %>
<%= @user.name %>
</div>
<!-- チャット一覧テンプレート -->
<div class="row chat-index mx-auto">
<%= render 'public/chats/chats', chats: @chats %>
</div>
</div>
</div>
</div>
<!-- チャット送信テンプレート -->
<div class="row mx-auto">
<%= render 'public/chats/form', chat: @chat %>
</div>
チャット一覧のテンプレート
わかりにくいのでシンプルに表示しています!
カスタマイズしてご使用ください!
<% chats.each do |chat| %>
<% if chat.user == current_user %>
<p><%= chat.message %></p>
<span><%= chat.created_at.strftime('%Y/%m/%d %H:%M') %></span>
<% else %>
<p><%= chat.message %></p>
<span><%= chat.created_at.strftime('%Y/%m/%d %H:%M') %></span>
<% end %>
<% end %>
チャット入力テンプレート
<%= form_with model: chat, local: false do |f| %>
<%= f.hidden_field :room_id %>
<%= f.text_field :message, class: "form-control chat_textfield", placeholder: "コメントを送信" %>
<button type="submit" class="btn btn-primary">
<i class="fas fa-paper-plane fa-lg" style="color: #ffffff;"></i>
</button>
<% end %>
ワンポイント🌱
form_withの非同期化は local: false
を忘れずに!
link_toを入れる場合は、remote: true
が必要!(今回はなし)
classまたはidを付与しよう!
私は記述が長くなるのが嫌でclassに付与していますが、idでもOKです!
⚠️上記の選択で、create.js.erb
書き方が少し異なります!
show.html.erb
<!-- チャット一覧テンプレート -->
+ <div class="row chat-index mx-auto">
<%= render 'public/chats/chats', chats: @chats %>
</div>
_form.html.erb
<%= form_with model: chat, local: false do |f| %>
<%= f.hidden_field :room_id %>
+ <%= f.text_field :message, class: "form-control chat_textfield", placeholder: "コメントを送信" %>
<button type="submit" class="btn btn-primary">
<i class="fas fa-paper-plane fa-lg" style="color: #ffffff;"></i>
</button>
<% end %>
create.jsの作成
$('.chat-index').html("<%= j(render "public/chats/chats", chats: @chats) %>");
$('.chat_textfield').val("");
注意⚠️
先ほどclassではなくidを付与した方は
'.chat-index'
ではなく、'#chat-index'
に修正してください
'#chat_textfield'
も同様です!
コントローラーの修正
非同期化はjsファイルを経由して画面表示が行われるため、
通常の処理の順番と異なります
そのためcreateアクションには追記が必要です
class Public::ChatsController < ApplicationController
def create
+ room = Room.find(params[:chat][:room_id])
+ @chats = room.chats
@chat = current_user.chats.new(chat_params)
@chat.save
end
end
createアクション時にcreate.js.erbで@chatsを呼び出すため
この記述が必要になります!
私はここのエラーで数時間溶かしてしまいました…😨
失敗談はこちら(笑)↓
もう少し詳しくここの部分の説明をしています!
おまけ
チャットの入力フォームを下に固定する方法をついでに書いておきます!
先ほどは省略していたformのviewはこんな感じです!
このcontainerについているfixed-bottom-form"
をcssで設定しています
<div class="container fixed-bottom-form">
<div class="row justify-content-center">
<div class="col-sm-12 col-md-10 col-lg-8">
<div class="col-md-8 mx-auto">
<%= form_with model: chat, local: false do |f| %>
<div class="input-group">
<%= f.hidden_field :room_id %>
<%= f.text_field :message, class: "form-control chat_textfield", placeholder: "コメントを送信" %>
<div class="input-group-append">
<button type="submit" class="btn btn-primary">
<i class="fas fa-paper-plane fa-lg" style="color: #ffffff;"></i>
</button>
:
/*チャットフォーム*/
.fixed-bottom-form {
position: fixed;
bottom: 85px;
left: 50%;
transform: translateX(-50%);
}
吹き出しにする方法はこちらの記事を参考にしました!
さいごに
いいねやコメント、フォローの非同期化を乗り越えてきたので、
余裕かと思いきやまさかの躓きでした!
理解が深められてよかったです!
参照記事
参考にさせていただきました!
ありがとうございました!