前提・実現したいこと
Ruby on rails/Ajax/JQuery
現在、チャット機能を持ったアプリ作成に伴い、Ajaxを使用した自動更新を実装しようとしております。
その際に以下のエラーが発生してしまっており、自身で色々と情報収集・確認しておりましたが、解決しなかったため、質問させていただきたく存じます。
実装したい内容:チャット機能+Ajaxを用いた非同期通信によるページの更新。
情報など不足しておりましたら、コメントいただけますと幸いです。
該当githubリポジトリ:https://github.com/Tatsu88-Tokyo/BulkFriends2
発生している問題・エラーメッセージ
エラー内容:新規投稿時、投稿した内容が非同期で更新されない。
(投稿しているページは反映されているが、他のウィンドウでその内容が反映されない)
エラーメッセージ:なし
該当のソースコード
:route resources :user, only: [:show, :edit, :update]do member do get 'profile' patch 'profile_update' get 'logout' get 'friends' get 'search' get :following, :followers resources :messages, only: [:index, :create] namespace :api do resources :messages, only: :index, defaults: { format: 'json' } end end end
:views/messages/index =render "home/header_login" .messages .messages__side .messages__side__header Messages .messages__side__contents %ul.message-friends %li.message-friends-list -@friends.each do |friend| .message-friend__line .line-message-name = link_to messages_path(friend),"data-turbolinks": false do =friend.nickname =link_to '詳細', user_path(friend),class:"detail" .messages__main .messages__main__header =@user.nickname .messages__main__contents .contents =render @messages .messages__main__footer .messages__main__footer__form = form_with model: @message,id: "new_message", local:true,"data-turbolinks": false do |f| = f.text_field :content, class: 'form__message', placeholder: 'type a message' .form__mask = f.label :image, class: 'form__mask__image' do %i.fas.fa-image.fa-2x = f.file_field :image, class: 'hidden' = f.submit 'Send', id: "msgbtn", class: 'form__submit'
:views/messages/_message .message{data: {message: {id: message.id}}} .upper-message .upper-message__user-name = message.user.nickname .upper-message__date = message.created_at.strftime("%Y年%m月%d日 %H時%M分") .lower-message - if message.content.present? %p.lower-message__content = message.content = image_tag message.image.url, class: 'lower-message__image' if message.image.present?
:controllers/message class MessagesController < ApplicationController before_action :set_user before_action :set_friend def index send_ids = current_user.messages.where(receive_user_id: @user.id).pluck(:id) receive_ids = @user.messages.where(receive_user_id: current_user.id).pluck(:id) @message=Message.new @messages = Message.where(id: send_ids + receive_ids).order(created_at: :asc) end def create @message = current_user.messages.new(message_params) @message.receive_user_id = @user.id if @message.save respond_to do |format| format.html{ redirect_to messages_path(@user)} format.json end else @messages = @user.messages.includes(:user) flash.now[:alert] = 'メッセージを入力してください。' redirect_to messages_path(@user) end end private def set_user @user = User.find(params[:id]) end def set_friend @friends = current_user.matchers end def message_params params.require(:message).permit(:content, :image).merge(user_id: current_user.id) end end
:controllers/api/messages class Api::MessagesController < ApplicationController def index @text = Message.where(user_id:current_user,receive_user_id:params[:id]) last_message_id = @text.ids.last @content = @text.find(last_message_id) user = User.find(@content.user_id) @messages = user.messages.where(user_id:current_user,receive_user_id:params[:id]).where("id > ?", last_message_id) end end
以下、console.logでlast_message_idをチェックしていたところ、新規投稿をしたページは、その投稿がlast_message_idとなっておりましたが、投稿をしていない別ウインドウでは投稿前のidがlast_message_idとなってしまっております。
:message.js $(function(){ let reloadMessages = function(){ if (location.href.match(//user/\d+/messages/)){ let last_message_id = $('.message:last').data('message-id'); console.log(last_message_id); $.ajax({ url:'api/messages', type:'get', dataType:'json', data: {id: last_message_id} }) .done(function (messages){ let insertHTML = ''; messages.forEach(function (message){ insertHTML = buildHTML(message); $('.contents').append(insertHTML); }) $('.messages__main__contents').animate({scrollTop: $('.contents')[0].scrollHeight}); }) .fail(function(){ alert('自動更新,失敗') }); } }; setInterval(reloadMessages, 3000); function buildHTML(message){ let image = message.image ? `<img class="lower-message__image" src=${message.image}>` : `` let html = `<div class="message" data-message-id = ${message.id}> <div class="upper-message"> <div class="upper-message__user-name"> ${message.name} </div> <div class="upper-message__date"> ${message.created_at} </div> </div> <div class="lower-message"> <p class="lower-message__content"> ${message.content} </p> ${image} </div> </div>`; return html } $('#new_message').on('submit',function(e){ e.preventDefault(); let formData = new FormData(this); let url = $(this).attr('action'); $.ajax({ url: url, type:"POST", data: formData, dataType: 'json', processData: false, contentType:false }) .done(function(message){ let html = buildHTML(message) $('.contents').append(html); $('.messages__main__contents').animate({scrollTop: $('.contents')[0].scrollHeight}); $('#new_message')[0].reset(); $('.form__submit').prop('disabled',false); }) .fail(function(){ alert('error!'); }) }) });
:views/api/index.json.jbuilder json.array! @messages do |message| json.content message.content json.name user.nickname json.image message.image.url json.created_at message.created_at.strftime("%Y年%m月%d日 %H時%M分") json.id message.id end
:views/messages/create.json.jbuilder json.name current_user.nickname json.content @message.content json.image @message.image.url json.created_at @message.created_at.strftime("%Y年%m月%d日 %H時%M分") json.id @message.id
以上
何卒よろしくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。