0
0

DM(チャット)機能 非同期化

Last updated at Posted at 2024-06-19

はじめに

非同期化の失敗を先ほどアウトプットしていましたが、
DM機能の非同期化もまとめておきたいと思います!

完成物

コメントは吹き出しをつけて、送信フォームは下に固定しています!

ER図

今回は非同期化のまとめなので実装方法は割愛しますが、
こちらのER図にて実装しています

スクリーンショット 2024-06-19 21.39.10.png

実装方法はこちらの記事が大変わかりやすかったです
⚠️全く同じというわけではないと思います!

Viewの記述

テンプレートの作成

非同期化に対応したい箇所をテンプレートにします
今回の場合は、チャット一覧とチャット送信フォームです

show.html.erb
<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.html.erb
<% 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.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 %>

ワンポイント🌱
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の作成

view/public/chats/create.js.erb
$('.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で設定しています

_form.html.erb
<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>
:
application.css
/*チャットフォーム*/
.fixed-bottom-form {
  position: fixed;
  bottom: 85px;
  left: 50%;
  transform: translateX(-50%);
}

吹き出しにする方法はこちらの記事を参考にしました!

さいごに

いいねやコメント、フォローの非同期化を乗り越えてきたので、
余裕かと思いきやまさかの躓きでした!
理解が深められてよかったです!

参照記事

参考にさせていただきました!
ありがとうございました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0