質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

2153閲覧

Ajaxを用いた非同期通信によるチャット機能実装時エラー発生に関する質問(新規投稿の内容が別ウインドウに反映されない。)

Tatsu88-Tokyo

総合スコア4

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/04/02 14:46

前提・実現したいこと

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

以上
何卒よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

API/messageコントローラーの記述における取得したメッセージの中から最も新しいメッセージの取得ができていませんでした。
そのため、以下のように記述を修正して、解決することができました。

class Api::MessagesController < ApplicationController def index text = Message.where(user_id:current_user,receive_user_id:params[:id]) # ajaxで送られてくる最後のメッセージのid番号を変数に代入 last_message_id = params[:last_id] # 取得したメッセージ達から、idがlast_message_idよりも新しい(大きい)メッセージ達のみを取得 @messages = text.includes(:user).where("id > ?", last_message_id) end end

投稿2020/04/21 10:56

Tatsu88-Tokyo

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問