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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

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

Ajax

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

Q&A

0回答

936閲覧

ActionCableを使ったチャットアプリで「undefined method `to_key' for〜」というエラーを解決したい

hazumi

総合スコア1

Ruby on Rails

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

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

Ajax

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

0グッド

0クリップ

投稿2021/06/15 13:47

編集2021/06/15 13:53

メッセージ送信時に生じるエラーの解決

プログラミング初心者で、Ruby on Rilsとjavascriptを使用し、オリジナルアプリを作ろうとしています。
現在は、ActionCableを用いた非同期通信のチャットアプリを製作しているところです。
メッセージを送信すると、エラーが出てしまいます。
ご指導いただきたいです。
よろしくお願いします。

undefined method `to_key' for〜エラーの解決

エラー文↓↓↓
NoMethodError (undefined method `to_key' for 1:Integer
Did you mean? to_query):

app/controllers/application_controller.rb:13:in block in render_with_signed_in_user' app/controllers/application_controller.rb:13:in tap'
app/controllers/application_controller.rb:13:in render_with_signed_in_user' app/models/message.rb:21:in template'
app/controllers/messages_controller.rb:12:in `create'

該当のソースコード

messagescontroller

1class MessagesController < ApplicationController 2 def index 3 @message = Message.new 4 @room = Room.find(params[:room_id]) 5 @messages = Message.includes(:user).order(:id) 6 @message = current_user.messages.build 7 end 8 9 def create 10 @room = Room.find(params[:room_id]) 11 @message = current_user.messages.create!(message_params) 12 ActionCable.server.broadcast'room_channel', message: @message.template 13 end 14 15 private 16 17 def message_params 18 params.require(:message).permit(:image, :content, :heat_id, :condition_id).merge(user_id: current_user.id, room_id: @room.id) 19 end 20 21 22end

model

1class Message < ApplicationRecord 2 belongs_to :room 3 belongs_to :user 4 has_one_attached :image 5 extend ActiveHash::Associations::ActiveRecordExtensions 6 belongs_to :heat 7 belongs_to :condition 8 9 with_options presence: true do 10 validates :heat_id 11 validates :condition_id 12 validates :content 13 end 14 15 with_options numericality: { other_than: 1, message: 'Select' } do 16 validates :heat_id 17 validates :condition_id 18 end 19 20 def template 21 ApplicationController.render_with_signed_in_user(user_id, partial: 'messages/message', locals: { message: self }) 22 end 23end

applicationcontroller

1class ApplicationController < ActionController::Base 2 before_action :configure_permitted_parameters, if: :devise_controller? 3 4 private 5 6 def configure_permitted_parameters 7 devise_parameter_sanitizer.permit(:sign_up, keys: [:name]) 8 devise_parameter_sanitizer.permit(:account_update, keys: [:name]) 9 end 10 11 def self.render_with_signed_in_user(user, *args) 12 ActionController::Renderer::RACK_KEY_TRANSLATION['warden'] ||= 'warden' 13 proxy = Warden::Proxy.new({}, Warden::Manager.new({})).tap{|i| i.set_user(user, scope: :user) } 14 renderer = self.renderer.new('warden' => proxy) 15 renderer.render(*args) 16 end 17end

js

1import consumer from "./consumer" 2 3 4 consumer.subscriptions.create("RoomChannel", { 5 connected() { 6 // Called when the subscription is ready for use on the server 7 }, 8 9 disconnected() { 10 // Called when the subscription has been terminated by the server 11 }, 12 13 received(data) { 14 document.getElementById('upper-message'). 15 insertAdjacentHTML('beforeend',data['message']) 16 } 17 }); 18

rb

1class RoomChannel < ApplicationCable::Channel 2 def subscribed 3 stream_from "room_channel" 4 end 5 6 def unsubscribed 7 # Any cleanup needed when channel is unsubscribed 8 end 9 10end

mainhtml

1<div class="chat-header"> 2 <div class="left-header"> 3 <div class="header-title"> 4 *<%= @room.room_name %>さんの連絡ルーム* 5 </div> 6 </div> 7 <div class="right-header"> 8 <div class="header-button"> 9 <a class="btn btn-danger" href="#">ルームを終了する</a> 10 </div> 11 </div> 12</div> 13 14<div id="messages"> 15 <%= render partial: 'message', collection: @messages %> 16</div> 17 18<%= form_with model: [@room, @message], class: 'form-box', id: "form-box" do |f| %> 19 <div class="form-input"> 20 <%= f.collection_select(:heat_id, Heat.all, :id, :name, {}, {class:"form-control", id:"select_box"}) %> 21 <%= f.collection_select(:condition_id, Condition.all, :id, :name, {}, {class:"form-control", id:"select_box"}) %> 22 <%= f.text_area :content, class: "form-control", placeholder:"メッセージを入力", id:"message_content", rows:"3" %> 23 <label class="form-image"> 24 <span class="btn btn-outline-dark">画像</span> 25 <%= f.file_field :image, class: "hidden" %> 26 </label> 27 </div> 28 <%= f.submit '送信', class:"btn btn-info", id:"submit" %> 29 30<% end %>

messagehtml

1<div class="message"> 2 <div id="upper-message"> 3 <% if message.user_id==current_user.id %> 4 <div class="user-date"> 5 <p><%= l message.created_at %></p> 6 </div> 7 <div class="mycomment"> 8 <div class="health-message"> 9 <p>【体温】<%= message.heat.name %> 【体調】<%= message.condition.name %></p> 10 </div> 11 <p><%= simple_format(message.content) %></p> 12 </div> 13 <div class="user-image"> 14 <%= image_tag message.image, class: 'message-image' if message.image.attached? %> 15 </div> 16 <% else %> 17 <div class="partner-date"> 18 <p><%= l message.created_at %></p> 19 </div> 20 <div class="fukidasi"> 21 <div class="message-user"> 22 <%= message.user.name %> 23 </div> 24 <div class="messaging"> 25 <div class="says"> 26 <div class="health-message"> 27 <p>【体温】<%= message.heat.name %> 【体調】<%= message.condition.name %></p> 28 </div> 29 <p><%= simple_format(message.content) %></p> 30 </div> 31 <div class="partner-image"> 32 <%= image_tag message.image, class: 'message-image' if message.image.attached? %> 33 </div> 34 </div> 35 </div> 36 <% end %> 37 </div> 38</div>

routes

1Rails.application.routes.draw do 2 mount ActionCable.server => '/cable' 3 get 'rooms/index' 4 devise_for :users 5 root to: "activities#index" 6 resources :users, only: [:edit, :update] 7 resources :activities, only: [:index, :new, :create, :show] 8 9 resources :rooms, only: [:index, :new, :create] do 10 resources :messages, only: [:index, :create] 11 end 12 13end 14

試したこと

①messages_controllerのcreateアクションをbinding.pryしました。
paramsは正しく送られていましたが、@message.templateを調べると、NoMethodError: undefined method `template' for nil:NilClassというエラー文が表示されました。

②上記のエラー分から、templateの定義が上手く読み込まれていないと考え、application_controllerに定義されているtemplateをmessages_controllerに移動させましたが、変化はありませんでした。

③render_with_signed_in_userのスペルミスがないか確認しましたが、正しく記述されていると思います。

エラー解決のための方法やアドバイスをいただけますでしょうか。
よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

Rails 6.0.3.7
Mysql

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問