簡易的なユーザ間のチャットを作成し、ajaxを用いた自動更新機能を利用しています。
メッセージを自動的に更新することはできたのですが、そのメッセージの投稿者名を取得することができず困っています。
Javascriptのコンソールには、「TypeError: undefined is not an object (evaluating 'message.user.name')」と表示されており、親モデルがきちんと取得できていないからだと思うのですが、、、message.user.nameのような形で、親モデル(User)のnameを取り出したいです。
Javascriptを詳細には理解していないので、説明不足な部分があるかもしれませんが、よろしくお願い致します。
開発環境:
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin17]
Rails 5.1.6.1
jquery-rails (4.3.3)
参考サイト:
https://qiita.com/yuki-n/items/885f6f059167a7b5aedc
View:
ruby
1<!--app/views/messages/index.html.erb--> 2 3<h1>Messages#index</h1> 4<p>Find me in app/views/messages/index.html.erb</p> 5 6<table> 7 <tbody> 8 <% @messages.each do |message| %> 9 <tr class="messages" data-id=<%= message.id %>> 10 <% if message.user == current_user %> 11 <td class="current_user"><%= message.user.name %></td> 12 <td class="current_user_said"><%= message.body %></td> 13 <% else %> 14 <td class="other_user"><%= message.user.name %></td> 15 <td class="other_user_said"><%= message.body %></td> 16 <% end %> 17 </tr> 18 <% end %> 19 </tbody> 20</table> 21
Models:
ruby
1# app/models/message.rb 2class Message < ApplicationRecord 3 belongs_to :room, optional: true 4 belongs_to :user, optional: true 5 validates :room_id, presence: true 6 validates :user_id, presence: true 7end
ruby
1# app/models/room.rb 2class Room < ApplicationRecord 3 belongs_to :owner, class_name: "User", foreign_key: "owner_user_id" 4 belongs_to :invited_user, class_name: "User", foreign_key: "invited_user_id" 5 has_many :messages 6 7 scope :between_users, -> (user1_id, user2_id) do 8 where(owner_user_id: user1_id, invited_user_id: user2_id).or( 9 where(owner_user_id: user2_id, invited_user_id: user1_id) 10 ) 11 end 12end
ruby
1# app/models/user.rb 2class User < ApplicationRecord 3 devise :database_authenticatable, :registerable, 4 :recoverable, :rememberable, :validatable, 5 :confirmable, :lockable, :timeoutable, :trackable and :omniauthable 6 validates :name, presence: true, length: { maximum: 30 } 7 validates :sex, presence: true 8 9 enum sex: { man: 1, woman: 2} 10 11 has_many :owned_rooms, class_name: "Room", foreign_key: "owner_user_id" 12 has_many :invited_rooms, class_name: "Room", foreign_key: "invited_user_id" 13 has_many :boards 14 has_many :messages 15end
Controller:
ruby
1# app/controller/messages_controller.rb 2class MessagesController < ApplicationController 3 def index 4 @room = Room.find(params[:room_id]) 5 @messages = @room.messages 6 respond_to do |format| 7 format.html 8 format.json { @new_message = Message.where('id > ?', params[:message][:id]) } 9 end 10 end 11end
Javascript側:
Javascript
1//app/assets/javascript/message.js 2$(function(){ 3 function buildMESSAGE(message) { 4 var messages = $('tbody').append('<tr class="messages" data-id=' + message.id + '><td>' + message.user.name + '</td><td>' + message.body + '</td></tr>'); 5 //'tbody'に'tr'以下のhtml全てをappend 6 } 7 8 $(function(){ 9 setInterval(update, 10000); 10 }); 11 function update(){ //この関数では以下のことを行う 12 if($('.messages')[0]){ //もし'messages'というクラスがあったら 13 var message_id = $('.messages:last').data('id'); //一番最後にある'messages'というクラスの'id'というデータ属性を取得し、'message_id'という変数に代入 14 } else { //ない場合は 15 var message_id = 0 //0を代入 16 } 17 $.ajax({ //ajax通信で以下のことを行う 18 url: location.href, //urlは現在のページを指定 19 type: 'GET', //メソッドを指定 20 data: { //railsに引き渡すデータは 21 message: { id: message_id } //このような形(paramsの形をしています)で、'id'には'message_id'を入れる 22 }, 23 dataType: 'json' //データはjson形式 24 }) 25 .always(function(data){ //通信したら、成功しようがしまいが受け取ったデータ(@new_message)を引数にとって以下のことを行う 26 $.each(data, function(i, data){ //'data'を'data'に代入してeachで回す 27 buildMESSAGE(data); //buildMESSAGEを呼び出す 28 }); 29 }); 30 } 31});
json
1<!--app/views/messages/index.json.jbuilder--> 2 3if @new_message.present? # @new_messageに中身があれば 4 json.array! @new_message # 配列かつjson形式で@new_messageを返す 5end
ルーティング:
Ruby
1# config/routes.rb 2Rails.application.routes.draw do 3 4 devise_for :users 5 root to: 'static_pages#home' 6 resources :boards 7 resources :rooms do 8 resources :messages 9 end 10 11 get 'users/index' 12end
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/07 07:17