Ruby on Rails6/Action Cableで簡単な1対1のチャットアプリを作りました。
メッセージの送受信は正常に動作してますが、表示部分で困りました。
相手は画面左側、自分は画面右側に表示するため、message.user_id(メッセージ発信者)とcurrent_user.idを比較する必要があります。
以下のように比較して左右に振り分けました。
テンプレートファイル
\app\views\messages_message.html.erb
ruby
1<div class='message' id="message-<%= message.id %>"> 2 <% if current_user_id != message.user.id %> 3 <div class="line__left"> 4 <figure><%= if message.user.avatar.file.nil? then image_pack_tag("no-avatar.jpg", class: "") else image_tag(message.user.avatar.url, class: "") end %></figure> 5 <div class="line__left-text"> 6 <div class="name"><%= message.user.name %></div> 7 <div class="text"><%= %>:<%= message.user.id %>:<%= simple_format(h message.text) %></div> 8 </div> 9 <span class="date"><%= l message.created_at, format: '%Y年%-m月%-d日(%a) %H:%M' %></span> 10 </div> 11 <% else %> 12 <div class="line__right"> 13 <div class="text"><%= %>:<%= message.user.id %>: <%= simple_format(h message.text) %></div> 14 <span class="date"><%= l message.created_at, format: '%Y年%-m月%-d日(%a) %H:%M' %></span> 15 </div> 16 <% end %> 17</div> 18
テンプレートを呼ぶ側
\app\views\rooms\show.html.erb
ruby
1 <div class="message__container" data-room_id="<%= @room.id %>"> 2 <%= render partial: 'messages/message', collection: @messages, locals: { current_user_id: current_user.id} %> 3 </div>
チャットルーム表示時(room/show)は、(DBから取得したデータのため)上記で振り分けられ正常に表示されます。
問題は入力したメッセージです。
上記のテンプレートを使うと、current_userは取得できないため使えません。
そこでreceived(data)のタイミングであれば、current_userと送信者の2点がそろうタイミングなので、ここでレンダリングしようと思いました。
javascript
1import consumer from "./consumer" 2 3document.addEventListener('turbolinks:load', () => { 4 5 // viewからcurrent_userを取得 6 let current_user_id = document.getElementsByClassName('message__current_user_id')[0].getAttribute('value'); 7 8 consumer.subscriptions.create("RoomChannel", { 9 connected() { 10 }, 11 12 disconnected() { 13 }, 14 15 received(data) { 16 17 // viewから取得したcurrent_user_id と 18 // サーバから受信したdata['sent_user'](送信者) 19 // が揃ったので、あとはレンダリングしたい 20 21 } 22 }) 23 24 25 26}); 27 28 29
テンプレート内の処理をhtmlで追加しようと思いました。
↓のように。
javascript
1 received(data) { 2 3 let h = '<div class="message" id="message-' + data['message_id'] + '">' 4 if(current_user_id != data['sent_user']){ 5 h = h + '<div class="line__left">' 6 7 } 8 else{ 9 h = h + '<div class="line__right">' 10 } 11 12 13 // サーバー側から受け取ったHTMLを一番最後に加える 14 messageContainer.insertAdjacentHTML('beforeend', h) 15 */ 16 17 }
ところが、rubyのメソッドも使用しているためすぐにこれはマズイと気付きました。
このような状況です。
何かjsからレンダリングする方法、あるいはもっと良い方法はないでしょうか?
経験少ないため方法が思いつかずにいます。
先輩方どうぞ宜しくお願いします。
補足
ログインに関して
deviseは使ってないです
railsチュートリアルのログイン機能を実装しました
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。